ListPreference summary not formatting
I have a ListPreference and I want to show the current entry in the summary. According to the docs for ListPreference.getSummary(), I'm supposed to be able to do this by including %s
in the summary string. Unfortunately, the activity just displays the %s
in the summary.
The XML is pretty standard:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:key="displayMode"
android:summary="@string/display_mode_summary"
android:title="@string/display_mode"
android:defaultValue="BOTH"
android:entries="@array/displayModes"
android:entryValues="@array/displayModeValues"
/>
</PreferenceScreen>
The value of the string display_mode_summary
is just %s
. (The value "BOTH"
is present in the displayModeValues
array.) If I subclass ListPreference like this:
public final class DisplayModePreference extends ListPreference {
// ...
@Override
public CharSequence getSummary() {
return String.format(super.开发者_如何学GogetSummary().toString(), getEntry());
}
}
then when the preferences activity starts, the current value is correctly interpolated into the summary. But when I click on the preference and select a different value from the dialog, when the dialog closes the summary still shows the now-old value. I need to close the preferences activity and restart it to see the change.
I've tried this in several emulators at different API levels. What do I need to so that the displayed summary always reflects the current value?
You could override "onDialogClosed" as below:
@override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
setSummary(getEntry());
}
}
This will set the summary of your preference to the text of the selected entry.
The original getSummary()
in ListPreference only works when getEntries()
, getEntryValues()
and defaultValue
are pre-populated when the Preference screen loads. So it works fine when you use a static fixed list of items, like a <string-array>
resource.
But if you are dynamically generating the entries
and entryValues
at runtime, you need to ensure that these lists are generated when the Preference screen loads in onCreate()
and also ensure that the defaultValue
is set. Something like this:
SettingsFragment.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListPreference listPreference = (ListPreference) findPreference("dynamiclistItems");
CharSequence[] entryDisplayNames = new CharSequence[3];
entryDisplayNames[0] = "Item A";
entryDisplayNames[1] = "Item B";
entryDisplayNames[2] = "Item C";
CharSequence[] entryValues = new CharSequence[3];
entryValues[0] = "Item A Value";
entryValues[1] = "Item B Value";
entryValues[2] = "Item C Value";
listPreference.setEntries(entryDisplayNames);
listPreference.setEntryValues(entryValues);
if (listPreference.getValue() == null ||
listPreference.getValue().equals("")) {
// There is no stored string in shared prefs.
// The user has not chosen any value. So make
// the summary display a default entry "Item A"
// display name, which is item 0 in the 'entries' list. Info:
// https://stackoverflow.com/questions/5197228/how-to-set-the-default-value-of-a-listpreference
listPreference.setValueIndex(0);
}
}
For static lists that are populated with <string-array>
, just ensure that android:defaultValue="..."
is defined, and that it points to a valid item in the 'values' array. For example: android:defaultValue="Item A Value"
This will ensure that the android:summary="%s"
will work properly for dynamically generated and static lists.
精彩评论