Ho un'attività di preferenza che utilizza un elenco di preferenze come definito dal mio file XML. Come impostare il riepilogo dell'attività dell'elenco sul valore selezionato?
Grazie!
Ho un'attività di preferenza che utilizza un elenco di preferenze come definito dal mio file XML. Come impostare il riepilogo dell'attività dell'elenco sul valore selezionato?
Grazie!
Risposte:
Il modo più semplice per farlo è solo quello di farlo fare ad Android per te. Supponendo che si desideri che il riepilogo corrisponda al valore selezionato, è possibile semplicemente impostare il riepilogo di ListPreference
su"%s"
utilizzando XML o il setSummary
metodo in Java. Per esempio:
<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" />
Android sostituirà %s
con il valore di stringa corrente della preferenza, come visualizzato dal ListPreference
selettore di. Anche il riepilogo dell'elenco verrà impostato correttamente quando si immette l'attività: non è necessario scrivere alcun codice speciale per impostarlo inizialmente.
Questo funziona anche con l'AndroidX ListPreference
.
Ho passato gran lunga troppo tempo pasticciare con SharedPreferences
gli ascoltatori, prima ho scoperto questo.
"%s"
? Nei miei test, "%s"
non funziona con Gingerbread e versioni precedenti.
androidx
.
È possibile utilizzare OnPreferenceChangeListener
per modificare dinamicamente il riepilogo. Il problema è che ottiene il valore selezionato (da android:entryValues
), non la didascalia ( android:entries
). Nel codice seguente ho usato toString()
, ma la soluzione corretta è trovare la didascalia per il valore. Comunque, l'idea funziona:
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;
}
});
}
}
Volevo anche ottenere qualcosa di simile, ma il problema con https://stackoverflow.com/a/8155029/592025 è che mostra il valore per la mia preferenza (come 1, 2 3 ecc.). Voglio mostrare la voce (stringa leggibile dall'uomo) corrispondente al valore selezionato.
Quindi l'ho cambiato in questo modo e funziona nel modo in cui ne ho bisogno.
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;
}
});
Il trucco è usare al getEntry()
posto di getValue()
e una volta modificato il valore, impostare il valore in modo esplicito e rileggere la voce.
Penso che quello che stai cercando sia molto semplice che tu possa pensare, aggiungi la seguente riga di codice al tuo Preference
articolo:
android:summary="%1$s"
Quindi sarà simile a questo:
<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" />
Per prima cosa ottieni un riferimento a ListPreference nel tuo onCreate. Puoi usare findPreference (). Per esempio:
ListPreference pref = (ListPreference) findPreference("thePreferencesKey");
Quindi, quando carichi per la prima volta l'attività e ogni volta che il valore delle preferenze viene modificato, utilizza il metodo che desideri per ottenere il valore di ListPreference e imposta il riepilogo con:
pref.setSummary(theNewString);
Questo è il codice che sto usando, non chiama setValue manualmente, poiché credo che questo sia già stato fatto in una fase successiva.
Ecco un esempio:
@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;
}
Questo è esattamente quello che ho fatto e funziona benissimo. In onSharedPreferenceChangeListener controllo semplicemente la chiave di ciò che viene modificato e quindi per ListPreferences lo converto di nuovo in Human readable (entry invece di entryValue) con le istruzioni if. Abbastanza semplice.
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"
/>
xml array
<?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>
Ecco una versione estesa della risposta di midhunhk che affronta anche l'utile stringa "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, tanto per essere chiari, android: summary viene rimosso dal relativo xml.
Ed ecco un modo per gestire l'aggiornamento del riepilogo della preferenza della suoneria a seguito di una selezione dell'utente.
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;
}
})
Hai un metodo bindPreferenceSummaryToValue sulla tua PreferenceActivity,
puoi facilmente aggiungere il riepilogo all'elenco in questo modo:
private static void bindPreferenceSummaryToValue(Preference preference) {
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getString(preference.getKey(), ""));
}
Sul tuo metodo OnCreate chiami la funzione bind in questo modo:
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_OF_THE_LIST)));
Puoi facilmente aggiungere altri riepiloghi allo stesso modo:
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_1)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_2)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.KEY_3)));
sotto onCreatePreferences fai questo:
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]);
}
}
}