Сводка ListPreference не форматируется

У меня есть ListPreference, и я хочу показать текущую запись в сводке. Согласно документам для ListPreference.getSummary(), я должен сделать это, включив %s в итоговую строку. К сожалению, действие просто отображает %s в сводке.

XML довольно стандартный:

<?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>

Значение строки display_mode_summary равно %s. (Значение "BOTH" присутствует в массиве displayModeValues.) Если я создаю подкласс ListPreference следующим образом:

public final class DisplayModePreference extends ListPreference {
    // ...

    @Override
    public CharSequence getSummary() {
        return String.format(super.getSummary().toString(), getEntry());
    }
}

затем, когда начинается действие настроек, текущее значение правильно интерполируется в сводку. Но когда я нажимаю на предпочтение и выбираю другое значение в диалоговом окне, когда диалоговое окно закрывается, в сводке по-прежнему отображается старое значение. Мне нужно закрыть действие настроек и перезапустить его, чтобы увидеть изменения.

Я пробовал это в нескольких эмуляторах на разных уровнях API. Что мне нужно сделать, чтобы отображаемая сводка всегда отражала текущее значение?


person Ted Hopp    schedule 18.07.2011    source источник


Ответы (2)


Вы можете переопределить «onDialogClosed», как показано ниже:

@override
protected void onDialogClosed(boolean positiveResult) {
    super.onDialogClosed(positiveResult);

    if (positiveResult) {
        setSummary(getEntry());
    }
}

Это установит сводку ваших предпочтений в текст выбранной записи.

person Jason    schedule 04.10.2011
comment
В итоге я реструктурировал свои настройки (по другим причинам), поэтому ListPreference вообще не использовался. Если бы мне понадобился ListPreference, я бы, вероятно, использовал это. Кажется глупым, что ListPreference автоматически не обновляет свою сводку после отображения списка. - person Ted Hopp; 05.10.2011
comment
Спасибо за этот ответ. Но мой CustomListPreference всегда отправляет positiveResult = false, и я не могу понять, почему. - person webmonkey; 19.06.2013

Исходный getSummary() в ListPreference работает только тогда, когда getEntries(), getEntryValues() и defaultValue предварительно заполнены при загрузке экрана настроек. Так что он отлично работает, когда вы используете статический фиксированный список элементов, например ресурс <string-array>.

Но если вы динамически генерируете entries и entryValues во время выполнения, вам необходимо убедиться, что эти списки генерируются при загрузке экрана предпочтений в onCreate(), а также убедитесь, что defaultValue установлено. Что-то вроде этого:

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

Для статических списков, заполненных <string-array>, просто убедитесь, что android:defaultValue="..." определено и указывает на допустимый элемент в массиве 'values'. Например: android:defaultValue="Item A Value"

Это обеспечит правильную работу android:summary="%s" для динамически генерируемых и статических списков.

person Mr-IDE    schedule 07.08.2018
comment
Это интересно. Однако это не объясняет проблему, с которой я столкнулся изначально, потому что записи и значения записей объявлялись как ссылки на <string-array> ресурсы в XML-файле настроек. Они не генерировались динамически. - person Ted Hopp; 08.08.2018
comment
Для статических списков просто убедитесь, что android:defaultValue="..." определено и указывает на допустимый элемент в массиве значений. Вам также может понадобиться вызвать listPreference.notifyChanged();, чтобы принудительно обновить сводку при щелчке элемента. - person Mr-IDE; 09.08.2018
comment
Этот вызов notifyChanged(), вероятно, был проблемой. Как показывает мой исходный пост, у меня уже было android:defaultValue в xml. - person Ted Hopp; 09.08.2018