如何在首选项摘要中显示 Android 首选项的当前值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/531427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I display the current value of an Android Preference in the Preference summary?
提问by nyenyec
This must come up very often.
这必须经常出现。
When the user is editing preferences in an Android app, I'd like them to be able to see the currently set value of the preference in the Preference
summary.
当用户在 Android 应用程序中编辑首选项时,我希望他们能够在Preference
摘要中看到首选项的当前设置值。
Example: if I have a Preference setting for "Discard old messages" that specifies the number of days after which messages need to be cleaned up. In the PreferenceActivity
I'd like the user to see:
示例:如果我有一个“丢弃旧邮件”的首选项设置,该设置指定需要清理邮件的天数。在PreferenceActivity
我希望用户看到:
"Discard old messages"<- title
“丢弃旧消息”<- 标题
"Clean up messages after xdays"<- summarywhere xis the current Preference value
“ x天后清理消息”<-摘要,其中x是当前的首选项值
Extra credit: make this reusable, so I can easily apply it to all my preferences regardless of their type (so that it work with EditTextPreference, ListPreference etc. with minimal amount of coding).
额外的功劳:使其可重用,因此我可以轻松地将其应用于我的所有首选项,而不管它们的类型如何(以便它以最少的编码与 EditTextPreference、ListPreference 等一起使用)。
回答by DozenCrows
There are ways to make this a more generic solution, if that suits your needs.
如果满足您的需求,有多种方法可以使其成为更通用的解决方案。
For example, if you want to generically have all list preferences show their choice as summary, you could have this for your onSharedPreferenceChanged
implementation:
例如,如果您想让所有列表首选项都显示为摘要,则可以将其用于您的onSharedPreferenceChanged
实现:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = findPreference(key);
if (pref instanceof ListPreference) {
ListPreference listPref = (ListPreference) pref;
pref.setSummary(listPref.getEntry());
}
}
This is easily extensible to other preference classes.
这很容易扩展到其他偏好类。
And by using the getPreferenceCount
and getPreference
functionality in PreferenceScreen
and PreferenceCategory
, you could easily write a generic function to walk the preference tree setting the summaries of all preferences of the types you desire to their toString
representation
并通过getPreferenceCount
与getPreference
在功能PreferenceScreen
和PreferenceCategory
,你可以很容易地编写一个通用函数走偏好树设置类型的所有喜好的你渴望自己的概要toString
表示
回答by EddieB
Here is my solution... FWIW
这是我的解决方案...... FWIW
package com.example.PrefTest;
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;
import android.preference.PreferenceGroup;
import android.preference.PreferenceManager;
public class Preferences extends PreferenceActivity implements
OnSharedPreferenceChangeListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
PreferenceManager.setDefaultValues(Preferences.this, R.xml.preferences,
false);
initSummary(getPreferenceScreen());
}
@Override
protected void onResume() {
super.onResume();
// 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) {
updatePrefSummary(findPreference(key));
}
private void initSummary(Preference p) {
if (p instanceof PreferenceGroup) {
PreferenceGroup pGrp = (PreferenceGroup) p;
for (int i = 0; i < pGrp.getPreferenceCount(); i++) {
initSummary(pGrp.getPreference(i));
}
} else {
updatePrefSummary(p);
}
}
private void updatePrefSummary(Preference p) {
if (p instanceof ListPreference) {
ListPreference listPref = (ListPreference) p;
p.setSummary(listPref.getEntry());
}
if (p instanceof EditTextPreference) {
EditTextPreference editTextPref = (EditTextPreference) p;
if (p.getTitle().toString().toLowerCase().contains("password"))
{
p.setSummary("******");
} else {
p.setSummary(editTextPref.getText());
}
}
if (p instanceof MultiSelectListPreference) {
EditTextPreference editTextPref = (EditTextPreference) p;
p.setSummary(editTextPref.getText());
}
}
}
回答by Robertas
Android documentationsays one can use a String formatting marker in getSummary()
:
Android文档说可以在以下位置使用字符串格式标记getSummary()
:
If the summary has a String formatting marker in it (i.e. "%s" or "%1$s"), then the current entry value will be substituted in its place.
如果摘要中有字符串格式标记(即“%s”或“%1$s”),则当前条目值将被替换。
Simply specifying android:summary="Clean up messages after %s days"
in ListPreference xml declaration worked for me.
只需android:summary="Clean up messages after %s days"
在 ListPreference xml 声明中指定对我有用。
Note:This only works for ListPreference
.
注意:这仅适用于ListPreference
.
回答by tdevaux
If you use PreferenceFragment
, this is how I solved it. It's self explanatory.
如果您使用PreferenceFragment
,这就是我解决它的方法。这是不言自明的。
public static class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onResume() {
super.onResume();
for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); ++i) {
Preference preference = getPreferenceScreen().getPreference(i);
if (preference instanceof PreferenceGroup) {
PreferenceGroup preferenceGroup = (PreferenceGroup) preference;
for (int j = 0; j < preferenceGroup.getPreferenceCount(); ++j) {
Preference singlePref = preferenceGroup.getPreference(j);
updatePreference(singlePref, singlePref.getKey());
}
} else {
updatePreference(preference, preference.getKey());
}
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
updatePreference(findPreference(key), key);
}
private void updatePreference(Preference preference, String key) {
if (preference == null) return;
if (preference instanceof ListPreference) {
ListPreference listPreference = (ListPreference) preference;
listPreference.setSummary(listPreference.getEntry());
return;
}
SharedPreferences sharedPrefs = getPreferenceManager().getSharedPreferences();
preference.setSummary(sharedPrefs.getString(key, "Default"));
}
}
回答by Youyougoslave
My option is to extend ListPreference and it's clean:
我的选择是扩展 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();
}
}
Then you add in your settings.xml:
然后在 settings.xml 中添加:
<yourpackage.ListPreferenceShowSummary
android:key="key" android:title="title"
android:entries="@array/entries" android:entryValues="@array/values"
android:defaultValue="first value"/>
回答by Palani
You can override default Preference classes and implement the feature.
您可以覆盖默认的 Preference 类并实现该功能。
public class MyListPreference extends ListPreference {
public MyListPreference(Context context) { super(context); }
public MyListPreference(Context context, AttributeSet attrs) { super(context, attrs); }
@Override
public void setValue(String value) {
super.setValue(value);
setSummary(getEntry());
}
}
Later in you xml you can use custom preference like
稍后在您的 xml 中,您可以使用自定义首选项,例如
<your.package.name.MyListPreference
android:key="noteInterval"
android:defaultValue="60"
android:title="Notification Interval"
android:entries="@array/noteInterval"
android:entryValues="@array/noteIntervalValues"
/>
回答by Subtle Fox
After several hours I've been spent to solve such problem I've implemented this code:
几个小时后,我一直在解决这样的问题,我已经实现了这段代码:
[UPDATE: the final version listing]
[更新:最终版本列表]
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);
}
}
That was the only solution that worked for me fine. Before I've tried to subclass from ListPreferences and to implement android:summary="bla bla bla %s". Neither worked.
这是唯一对我有用的解决方案。在我尝试从 ListPreferences 继承子类并实现 android:summary="bla bla bla %s" 之前。都没有工作。
回答by Eruvanos
Maybe like ListPreference: Modify getSummary to get what you want:
也许像 ListPreference:修改 getSummary 以获得你想要的:
package your.package.preference;
import android.content.Context;
import android.util.AttributeSet;
public class EditTextPreference extends android.preference.EditTextPreference{
public EditTextPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public EditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextPreference(Context context) {
super(context);
}
@Override
public CharSequence getSummary() {
if(super.getSummary() == null) return null;
String summary = super.getSummary().toString();
return String.format(summary, getText());
}
}
And use this in your xml:
并在您的 xml 中使用它:
<your.package.EditTextPreference
android:key="pref_alpha"
android:summary="Actual value: %s"
android:title="Title"
android:defaultValue="default"
/>
So you are able to write a summary with %s
instead of the actual value.
因此,您可以使用%s
而不是实际值来编写摘要。
回答by Koem
This is the code you need to set the summary to the chosen value. It also sets the values on startup and respects the default values, not only on change. Just change "R.layout.prefs" to your xml-file and extend the setSummary-method to your needs. It actually is only handling ListPreferences, but it is easy to customize to respect other Preferences.
这是将摘要设置为所选值所需的代码。它还在启动时设置值并遵守默认值,而不仅仅是在更改时。只需将“R.layout.prefs”更改为您的 xml 文件并根据您的需要扩展 setSummary-method。它实际上只处理 ListPreferences,但很容易自定义以尊重其他 Preferences。
package de.koem.timetunnel;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceGroup;
public class Prefs
extends PreferenceActivity
implements OnSharedPreferenceChangeListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.addPreferencesFromResource(R.layout.prefs);
this.initSummaries(this.getPreferenceScreen());
this.getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
/**
* Set the summaries of all preferences
*/
private void initSummaries(PreferenceGroup pg) {
for (int i = 0; i < pg.getPreferenceCount(); ++i) {
Preference p = pg.getPreference(i);
if (p instanceof PreferenceGroup)
this.initSummaries((PreferenceGroup) p); // recursion
else
this.setSummary(p);
}
}
/**
* Set the summaries of the given preference
*/
private void setSummary(Preference pref) {
// react on type or key
if (pref instanceof ListPreference) {
ListPreference listPref = (ListPreference) pref;
pref.setSummary(listPref.getEntry());
}
}
/**
* used to change the summary of a preference
*/
public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
Preference pref = findPreference(key);
this.setSummary(pref);
}
// private static final String LOGTAG = "Prefs";
}
koem
科姆
回答by dhaag23
Actually, CheckBoxPreferencedoes have the ability to specify a different summary based on the checkbox value. See the android:summaryOff and android:summaryOn attributes (as well as the corresponding CheckBoxPreference methods).
实际上,CheckBoxPreference确实能够根据复选框值指定不同的摘要。请参阅 android:summaryOff 和 android:summaryOn 属性(以及相应的 CheckBoxPreference 方法)。