如何在Android Preference摘要中显示当前值?

476

这种情况经常出现。

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

例如:如果我有一个Preference设置“丢弃旧消息”,指定多少天后需要清理消息。在PreferenceActivity中,我希望用户看到:

“丢弃旧消息” <- 标题

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

额外加分:使其可重复使用,以便我可以轻松地将其应用于所有首选项,而不考虑它们的类型(因此它使用最少的编码与EditTextPreference、ListPreference等一起使用)。

36个回答

12

EditTextPreference使用说明:

public class MyEditTextPreference extends EditTextPreference {
    public MyEditTextPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

11

实际上,CheckBoxPreference 具有根据复选框的值指定不同摘要的功能。请查看 android:summaryOff 和 android:summaryOn 属性(以及相应的 CheckBoxPreference 方法)。


11

如果有人仍在寻找答案,您应该查看 thirtythreeforty的回答。

<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将使用ListPreference选择器显示的首选项当前字符串值替换%s。


可以用。这是目前最简单和最好的解决方案。 - davidgyoung
1
请注意,“%s”可以放置在摘要字符串的任何位置。是的,这包括资源字符串! - SMBiggs

7

我看到所有被投票的答案都展示了如何设置摘要与确切的当前值,但是OP也想要像下面这样的东西:

"在x天后清理消息" * <- 摘要,其中x是当前首选项值

这里是我的答案

根据文档上的 ListPreference.getSummary():

返回此ListPreference的摘要。如果摘要中有一个字符串格式标记(即“%s”或“%1 $ s”),则当前输入值将替换其位置。

然而,我在几台设备上尝试了这个方法,似乎不起作用。通过一些研究,我在 这个答案 中找到了一个好的解决方案。它简单地包括扩展您使用的每个Preference并覆盖getSummary()以按照Android文档指定的方式工作。


1
它似乎最初是有效的,但当您选择新值时,它不会自动更新,直到您执行某些操作来使整个活动无效并导致其重新绘制。我使用的是Android 4.0.4。 - eidylon
如果Google能够在首选项对象中添加格式化字符串,那就太好了。 - Justin Smith

7

谢谢这个提示!

我有一个偏好设置界面,希望显示每个列表偏好设置的值作为摘要。

目前我的做法是:

public class Preferences extends PreferenceActivity implements OnSharedPreferenceChangeListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
}

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

    // Set up initial values for all list preferences
    Map<String, ?> sharedPreferencesMap = getPreferenceScreen().getSharedPreferences().getAll();
    Preference pref;
    ListPreference listPref;
    for (Map.Entry<String, ?> entry : sharedPreferencesMap.entrySet()) {
        pref = findPreference(entry.getKey());
        if (pref instanceof ListPreference) {
            listPref = (ListPreference) pref;
            pref.setSummary(listPref.getEntry());
        }
    }

    // Set up a listener whenever a key changes            
    getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

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

    // Unregister the listener whenever a key changes            
    getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);    
}

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

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

这对我来说可行,但我想知道什么是最佳解决方案(性能、稳定性、可扩展性):Koem展示的还是这个?


6

感谢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),同样适用这个变更。

谢谢!

Chris


5
在Android Studio中,打开“root_preferences.xml”,选择“设计模式”。选择所需的EditTextPreference首选项,在“所有属性”下查找“useSimpleSummaryProvider”属性并将其设置为true。然后它将显示当前值。

重复的答案,但我喜欢这个解决方案。 - Marcel Hofgesang

4
public class ProfileManagement extends PreferenceActivity implements
OnPreferenceChangeListener {
    EditTextPreference screenName;
    ListPreference sex;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.layout.profile_management);

            screenName = (EditTextPreference) findPreference("editTextPref");
            sex = (ListPreference) findPreference("sexSelector");

            screenName.setOnPreferenceChangeListener(this);
            sex.setOnPreferenceChangeListener(this);

    }   

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        preference.setSummary(newValue.toString());
        return true;
    }
}

4
我用ListPreference的下属类解决了这个问题:
public class EnumPreference extends ListPreference {

    public EnumPreference(Context aContext, AttributeSet attrs) {
        super(aContext,attrs);
    }

    @Override
    protected View onCreateView(ViewGroup parent) {
        setSummary(getEntry());
        return super.onCreateView(parent);
    }

    @Override
    protected boolean persistString(String aNewValue) {
        if (super.persistString(aNewValue)) {
            setSummary(getEntry());
            notifyChanged();
            return true;
        } else {
            return false;
        }
    }
}

在1.6版本到4.0.4版本上,它对我来说似乎可以正常运行。


3

简单来说:

listPreference.setSummary("%s");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接