这个问题肯定经常出现。

当用户在Android应用程序中编辑首选项时,我希望他们能够在首选项摘要中看到当前设置的首选项值。

例如:如果我有“丢弃旧消息”的首选项设置,该设置指定了需要清理消息的天数。在PreferenceActivity中,我想让用户看到:

"丢弃旧消息" <- title

“x天后清理消息”<- summary,其中x是当前首选项值

额外的学分:使此可重用,所以我可以很容易地将它应用到我的所有首选项,而不管它们的类型(使它与EditTextPreference, ListPreference等工作,只需最少的编码)。


当前回答

我发现这种方法使EditTextPreference从支持库句柄“%s”在总结(因为ListPreference已经处理):

public class EditTextPreference extends android.support.v7.preference.EditTextPreference {
    public EditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void setText(String text) {
        super.setText(text);
        notifyChanged();
    }

    @Override
    public CharSequence getSummary() {
        String text = super.getText();
        String summary = super.getSummary().toString();
        return String.format(summary, text == null ? "" : text);
    }
}

在xml中它看起来是这样的:

<com.example.yourapp.EditTextPreference
    android:defaultValue="1"
    android:key="cleanup_period"
    android:summary="Clean up messages after %s days"
    android:title="Clean up period" />

其他回答

谢谢Reto的详细解释!

为了对大家有所帮助,我不得不修改Reto Meier提出的代码,使其与Android 1.5的SDK兼容

@Override
protected void onResume() {
    super.onResume();

    // Setup the initial values
    mListPreference.setSummary("Current value is " + mListPreference.getEntry().toString()); 

    // Set up a listener whenever a key changes            
    ...
}

同样的变化适用于回调函数onSharedPreferenceChanged(SharedPreferences SharedPreferences, String key)

欢呼,

克里斯

如果适合您的需求,有一些方法可以使其成为更通用的解决方案。

例如,如果你想让所有的列表首选项显示为摘要,你可以为你的onSharedPreferenceChanged实现:

public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    Preference pref = findPreference(key);

    if (pref instanceof ListPreference) {
        ListPreference listPref = (ListPreference) pref;
        pref.setSummary(listPref.getEntry());
    }
}

这很容易扩展到其他首选项类。

通过使用PreferenceScreen和PreferenceCategory中的getPreferenceCount和getPreference功能,您可以轻松地编写一个泛型函数来遍历首选项树,设置所需类型的所有首选项的摘要到它们的toString表示

在我花了几个小时来解决这样的问题后,我实现了以下代码:

[更新:最终版本列表]

public class MyPreferencesActivity extends PreferenceActivity {
    ...
    ListPreference m_updateList;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);

        m_updateList = (ListPreference) findPreference(getString(R.string.pref_update_interval_key));
        String currentValue = m_updateList.getValue();
        if (currentValue == null) {
            m_updateList.setValue((String)m_updateList.getEntryValues()[DEFAULT_UPDATE_TIME_INDEX]);
            currentValue = m_updateList.getValue();
        }
        updateListSummary(currentValue);    

        m_updateList.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                updateListSummary(newValue.toString());
                return true;
            }       
        });     
    }

    private void updateListSummary(String newValue) {
        int index = m_updateList.findIndexOfValue(newValue);
        CharSequence entry = m_updateList.getEntries()[index];
        m_updateList.setSummary(entry);
    }
}

这是唯一对我有效的解决方法。在我尝试子类从ListPreferences和实现android:summary="bla bla bla %s"。既不工作。

Android文档说可以在getSummary()中使用String格式标记:

如果摘要中有一个字符串格式标记(即。“%s”或“%1$s”),则当前条目的值将被替换。

在ListPreference xml声明中简单地指定android:summary=“在%s天后清理消息”对我来说很有效。

注意:这只适用于ListPreference。

如果有人还在寻找这个问题的答案,你应该看看三十三四十的答案。

<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会将%s替换为首选项的当前字符串值,就像ListPreference的选择器显示的那样。