Eu tenho uma atividade de preferência que usa uma lista de preferências conforme definido por meu arquivo XML. Como eu definiria o resumo da atividade da lista com o valor selecionado?
Obrigado!
Eu tenho uma atividade de preferência que usa uma lista de preferências conforme definido por meu arquivo XML. Como eu definiria o resumo da atividade da lista com o valor selecionado?
Obrigado!
Respostas:
A maneira mais simples de fazer isso é deixar que o Android faça isso por você. Supondo que você quer o resumo para corresponder ao valor selecionado, você pode simplesmente definir o resumo do ListPreferenceque"%s" usando XML ou o setSummarymétodo em Java. Por exemplo:
<ListPreference
android:key="pref_list"
android:title="A list of preferences"
android:summary="%s"
android:entries="@array/pref_list_entries"
android:entryValues="@array/pref_list_entries_values"
android:defaultValue="0" />
O Android substituirá %spelo valor da string atual da preferência, conforme exibido pelo ListPreferenceseletor do. O resumo da lista também será definido corretamente quando você entrar na atividade - você não precisa escrever nenhum código especial para configurá-la inicialmente.
Isso também funciona com o AndroidX ListPreference.
Passei muito tempo demais mucking com SharedPreferencesouvintes antes que eu descobri isso.
"%s"? Em meus testes, "%s"não funciona com o Gingerbread e versões anteriores.
androidx.
Você pode usar OnPreferenceChangeListenerpara alterar dinamicamente o resumo. O problema é que ele obtém o valor selecionado (de android:entryValues), não a legenda ( android:entries). Usei o código a seguir toString(), mas a solução adequada é encontrar a legenda para o valor. De qualquer forma, a ideia funciona:
public class Preferences extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.your_prefs);
ListPreference listPreference = (ListPreference) findPreference("preference_key");
if(listPreference.getValue()==null) {
// to ensure we don't get a null value
// set first value by default
listPreference.setValueIndex(0);
}
listPreference.setSummary(listPreference.getValue().toString());
listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
preference.setSummary(newValue.toString());
return true;
}
});
}
}
Eu também queria conseguir algo semelhante, mas o problema com https://stackoverflow.com/a/8155029/592025 é que ele mostra o valor da minha preferência (como 1, 2 3 etc.). Desejo mostrar a entrada (string legível por humanos) correspondente ao valor selecionado.
Então mudei dessa forma e funciona da maneira que preciso.
listPreference.setSummary(servicePreference.getEntry().toString());
listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Set the value as the new value
listPreference.setValue(newValue.toString());
// Get the entry which corresponds to the current value and set as summary
preference.setSummary(listPreference.getEntry());
return false;
}
});
O truque é usar em getEntry()vez de getValue()e depois que o valor for alterado, definir o valor explicitamente e ler a entrada.
Acho que o que você está procurando é muito simples do que você pode imaginar, adicione a seguinte linha de código ao seu Preferenceitem:
android:summary="%1$s"
Portanto, será mais ou menos assim:
<ListPreference
android:key="@string/pref_temp_key"
android:title="@string/pref_temp_title"
android:dialogTitle="@string/pref_temp_dialog_title"
android:entries="@array/pref_tempUnit_entries"
android:entryValues="@array/pref_tempUnit_entries"
android:summary="%1$s"
android:defaultValue="@string/pref_temp_default_value" />
Primeiro, obtenha uma referência a ListPreference em seu onCreate. Você pode usar findPreference (). Por exemplo:
ListPreference pref = (ListPreference) findPreference("thePreferencesKey");
Então, quando você carregar a Activity pela primeira vez e sempre que o valor de preferências for alterado, use qualquer método que você deseja obter o valor de ListPreference e defina o resumo com:
pref.setSummary(theNewString);
Este é o código que estou usando, não chama setValue manualmente, pois acredito que isso já seja feito em um estágio posterior.
Aqui está um exemplo:
@Override
public boolean onPreferenceChange(Preference preference, Object value)
{
String textValue = value.toString();
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(textValue);
CharSequence[] entries = listPreference.getEntries();
preference.setSummary(
index >= 0
? entries[index]
: null);
return true;
}
Isso é exatamente o que eu fiz e funciona muito bem. No onSharedPreferenceChangeListener , apenas verifico a chave do que está sendo alterado e, em ListPreferences, converto de volta para Human legable (entrada em vez de entryValue) com as instruções if. Bem simples.
public class MyPreferences extends PreferenceFragment implements OnSharedPreferenceChangeListener{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
context = getActivity();
if (context == null){
Log.e("error","context is null");
}
prefs = PreferenceManager.getDefaultSharedPreferences(context);
myFrequencyList = (Preference) findPreference("frequency_key");
prefs.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if(key.equals("frequency_key")){
String freq = sharedPreferences.getString("frequency_key", "8k Hz");
if(freq.equals("8000")){
freq = "8k Hz";
}
else if(freq.equals("16000")){
freq = "16k Hz";
}
else if(freq.equals("22050")){
freq = "22.05k Hz";
}
else if(freq.equals("44100")){
freq = "44.1k Hz";
}
else if(freq.equals("48000")){
freq = "48k Hz";
}
else{
freq = "8k Hz";
}
myFrequencyList.setSummary(freq);
}
layout xml
<ListPreference android:id="@+id/frequency_list"
android:key="frequency_key"
android:summary="8000"
android:title="Sample Rate"
android:defaultValue="8000"
android:dialogTitle="Larger sample rates create better sound quality but larger file sizes."
android:entries="@array/freq_titles"
android:entryValues="@array/freq_values"
/>
array xml
<?xml version="1.0" encoding="utf-8"?>
<string-array name="freq_titles">
<item>48k Hz</item>
<item>44.1k Hz</item>
<item>22.05k Hz</item>
<item>16k Hz</item>
<item>8k Hz</item>
</string-array>
<string-array name="freq_values">
<item>48000</item>
<item>44100</item>
<item>22050</item>
<item>16000</item>
<item>8000</item>
</string-array>
Aqui está uma versão expandida da resposta de midhunhk que também aborda a útil string "android: summary"
// Retrieve & populate flash modes
List<String> flashmodes = params.getSupportedFlashModes();
if (flashmodes != null) {
final ListPreference lp = (ListPreference) findPreference("flash_list");
final String lp_basesummary = "Set the Flash mode. The default is 'auto'";
lp.setEntries(flashmodes.toArray(new CharSequence[flashmodes.size()]));
lp.setEntryValues(flashmodes.toArray(new CharSequence[flashmodes.size()]));
// If there's only one option, make it the default
if (flashmodes.size() == 1)
lp.setValueIndex(0);
lp.setSummary(lp_basesummary + " [" + lp.getEntry() + "]");
lp.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Set the value as the new value
lp.setValue(newValue.toString());
// Get the entry which corresponds to the current value
// and set as summary
preference.setSummary(lp_basesummary + " [" + lp.getEntry() + "]");
return false;
}
});
} else {
// Remove the preference
((PreferenceGroup) findPreference("camera_preference")).removePreference(findPreference("flash_list"));
}
// Retrieve & populate focus modes
List<String> focusmodes = params.getSupportedFocusModes();
if (focusmodes != null) {
final ListPreference lp = (ListPreference) findPreference("focus_mode_list");
final String lp_basesummary = "Set the Focus mode. The default is 'auto'";
...
E, só para ficar claro, android: summary foi removido do xml relacionado.
E aqui está uma maneira de lidar com a atualização do resumo das preferências de toque após a seleção do usuário.
final SharedPreferences preference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
final RingtonePreference rp_shuttle = (RingtonePreference) findPreference("shuttle_tone");
rp_shuttle.setSummary(RingtoneManager
.getRingtone(getApplicationContext(), Uri.parse(preference.getString("shuttle_tone", "DEFAULT_SOUND")))
.getTitle(this));
rp_shuttle.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference mypreference, Object newValue) {
rp_shuttle.setSummary(RingtoneManager.getRingtone(getApplicationContext(), Uri.parse(newValue + ""))
.getTitle(getApplicationContext()));
return true;
}
})
Você tem um método bindPreferenceSummaryToValue em seu PreferenceActivity,
você pode adicionar facilmente o resumo à lista fazendo o seguinte:
private static void bindPreferenceSummaryToValue(Preference preference) {
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getString(preference.getKey(), ""));
}
No método OnCreate, você chama a função de ligação assim:
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_OF_THE_LIST)));
Você pode adicionar outros resumos facilmente da mesma maneira:
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_1)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_2)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_3)));
em onCreatePreferences faça isso ::
SharedPreferences sharedPreferences =getPreferenceScreen().getSharedPreferences();
PreferenceScreen prefScreen = getPreferenceScreen();
int count = prefScreen.getPreferenceCount();
for (int i = 0; i < count; i++) {
Preference p = prefScreen.getPreference(i);
if (p instanceof ListPreference) {
String value = sharedPreferences.getString(p.getKey(), "");
ListPreference listPreference = (ListPreference) preference;
int prefIndex = listPreference.findIndexOfValue(stringValue);
if (prefIndex >= 0) {
preference.setSummary(listPreference.getEntries()[prefIndex]);
}
}
}