Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android List Preferences: have summary as selected value?

Tags:

java

android

The simplest way to do this is just to have Android do it for you. Assuming you want the summary to match the selected value, you can simply set the summary of the ListPreference to "%s" using either XML or the setSummary method in Java. For example:

<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 will replace %s with the current string value of the preference, as displayed by the ListPreference's picker. The list's summary will also be set correctly when you enter the activity—you don't have to write any special code to set it up initially.

This also works with the AndroidX ListPreference.

I spent far too much time mucking with SharedPreferences listeners before I discovered this.


You can use OnPreferenceChangeListener to dynamically change the summary. The problem is that it gets the selected value (from android:entryValues), not the caption (android:entries). In the following code I used toString(), but the proper solution is to find the caption for the value. Anyways, the idea works:

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;
            }
        });
    }
}

I also wanted to achieve something similar, but the problem with https://stackoverflow.com/a/8155029/592025 is that, it shows the value for my preference (like 1, 2 3 etc). I want to show the entry (human readable string) corresponding to the selected value.

So I changed it this way and works the way I need it.

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;
        }
    });

The trick is to use getEntry() instead of getValue() and once the value is changed, to set the value explicitly and read back the entry.


I think that what you are looking for is much simple that you can think, add the following code line to your Preference item:

android:summary="%1$s"

So it will look something like this:

<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" />

So simple - just add the following property to your XML definition -

<ListPreference
...    
app:useSimpleSummaryProvider="true"
...
/>

First get a reference to the ListPreference in your onCreate. You can use findPreference(). For example:

ListPreference pref = (ListPreference) findPreference("thePreferencesKey");

Then, when you first load the Activity and whenever the preferences value is changed, use whatever method you want to get the value of the ListPreference and set the summary with:

pref.setSummary(theNewString);