这个问题肯定经常出现。
当用户在Android应用程序中编辑首选项时,我希望他们能够在首选项摘要中看到当前设置的首选项值。
例如:如果我有“丢弃旧消息”的首选项设置,该设置指定了需要清理消息的天数。在PreferenceActivity中,我想让用户看到:
"丢弃旧消息" <- title
“x天后清理消息”<- summary,其中x是当前首选项值
额外的学分:使此可重用,所以我可以很容易地将它应用到我的所有首选项,而不管它们的类型(使它与EditTextPreference, ListPreference等工作,只需最少的编码)。
在我花了几个小时来解决这样的问题后,我实现了以下代码:
[更新:最终版本列表]
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"。既不工作。
如果您只想显示每个字段的纯文本值作为摘要,那么下面的代码应该是最容易维护的。它只需要两处更改(第13行和第21行,标记为“此处更改”):
package com.my.package;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
public class PreferencesActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
private final String[] mAutoSummaryFields = { "pref_key1", "pref_key2", "pref_key3" }; // change here
private final int mEntryCount = mAutoSummaryFields.length;
private Preference[] mPreferenceEntries;
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences_file); // change here
mPreferenceEntries = new Preference[mEntryCount];
for (int i = 0; i < mEntryCount; i++) {
mPreferenceEntries[i] = getPreferenceScreen().findPreference(mAutoSummaryFields[i]);
}
}
@SuppressWarnings("deprecation")
@Override
protected void onResume() {
super.onResume();
for (int i = 0; i < mEntryCount; i++) {
updateSummary(mAutoSummaryFields[i]); // initialization
}
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); // register change listener
}
@SuppressWarnings("deprecation")
@Override
protected void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); // unregister change listener
}
private void updateSummary(String key) {
for (int i = 0; i < mEntryCount; i++) {
if (key.equals(mAutoSummaryFields[i])) {
if (mPreferenceEntries[i] instanceof EditTextPreference) {
final EditTextPreference currentPreference = (EditTextPreference) mPreferenceEntries[i];
mPreferenceEntries[i].setSummary(currentPreference.getText());
}
else if (mPreferenceEntries[i] instanceof ListPreference) {
final ListPreference currentPreference = (ListPreference) mPreferenceEntries[i];
mPreferenceEntries[i].setSummary(currentPreference.getEntry());
}
break;
}
}
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
updateSummary(key);
}
}
我已经看到了所有投票的答案,展示了如何用准确的当前值设置摘要,但OP也想要这样的东西:
“x天后清理消息”* <- summary,其中x是当前首选项值
以下是我实现这一目标的答案
根据ListPreference.getSummary()上的文档:
返回此ListPreference的摘要。如果摘要中有一个字符串格式标记(即。“%s”或“%1$s”),然后是当前值
输入值将被替换在其位置上。
然而,我在几台设备上尝试了这一功能,似乎不起作用。通过一些研究,我在这个答案中找到了一个很好的解决方案。它简单地由扩展你使用的每个Preference和覆盖getSummary()组成,以按照Android文档指定的方式工作。
谢谢你的建议!
我有一个首选项屏幕,并希望显示每个列表首选项的值作为摘要。
这就是我现在的方式:
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展示的那个还是这个?
我的选择是扩展ListPreference,它是干净的:
public class ListPreferenceShowSummary extends ListPreference {
private final static String TAG = ListPreferenceShowSummary.class.getName();
public ListPreferenceShowSummary(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ListPreferenceShowSummary(Context context) {
super(context);
init();
}
private void init() {
setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference arg0, Object arg1) {
arg0.setSummary(getEntry());
return true;
}
});
}
@Override
public CharSequence getSummary() {
return super.getEntry();
}
}
然后你添加你的settings.xml:
<yourpackage.ListPreferenceShowSummary
android:key="key" android:title="title"
android:entries="@array/entries" android:entryValues="@array/values"
android:defaultValue="first value"/>