我如何显示一个Android首选项的当前值在首选项摘要?

这个问题肯定经常出现。

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

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

“丢弃旧信息” <-标题

"在x天后清理消息" <- 总结,其中x是当前的Preference值

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

183284 次浏览

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

例如,如果你想一般地让所有列表首选项以摘要的形式显示它们的选择,你可以为你的onSharedPreferenceChanged实现这样做:

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


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

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

通过使用PreferenceScreenPreferenceCategory中的getPreferenceCountgetPreference功能,你可以很容易地编写一个泛型函数来遍历首选项树,将你想要的类型的所有首选项的摘要设置为它们的toString表示

谢谢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)

欢呼,

克里斯

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

这是将摘要设置为所选值所需的代码。它还在启动时设置值,并尊重默认值,而不仅仅是在更改时。只需要改变“r.b olayout”。并根据需要扩展setsummary -方法。它实际上只处理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

谢谢你的建议!

我有一个首选项屏幕,并希望显示每个列表首选项的值作为摘要。

这就是我现在的方式:

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展示的那个还是这个?

这是我的解决方案……就其价值而言

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

我的选择是扩展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"/>

要将ListPreference的摘要设置为对话框中选择的值,可以使用以下代码:

package yourpackage;


import android.content.Context;
import android.util.AttributeSet;


public class ListPreference extends android.preference.ListPreference {


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


protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) setSummary(getEntry());
}


protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
super.onSetInitialValue(restoreValue, defaultValue);
setSummary(getEntry());
}
}

并在你的preferences.xml中引用yourpackage.ListPreference对象,记住在那里指定你的android:defaultValue,因为这会触发对onSetInitialValue()的调用。

如果你愿意,你可以在调用setSummary()之前修改文本,以适合你的应用程序。

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

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

简单地在ListPreference xml声明中指定android:summary="Clean up messages after %s days"就可以了。

这只适用于ListPreference

我已经看到了所有投票的答案,展示了如何用准确的当前值设置摘要,但OP也想要这样的东西:

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

以下是我实现这一目标的答案

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

返回该ListPreference的摘要。如果摘要中有字符串格式标记(即"% "或者“%1$ "”,然后是电流

然而,我在几台设备上尝试了这一功能,似乎不起作用。经过一些研究,我在这个答案中找到了一个很好的解决方案。它只是由扩展你使用的每个Preference和覆盖getSummary()组成,以按照Android文档指定的方式工作。

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

[更新:最终版本列表]

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"。既不工作。

我解决了这个问题与以下后代的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,我似乎工作得很好。

您可以覆盖默认的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());
}
}

稍后在xml中,您可以使用自定义首选项,如

<your.package.name.MyListPreference
android:key="noteInterval"
android:defaultValue="60"
android:title="Notification Interval"
android:entries="@array/noteInterval"
android:entryValues="@array/noteIntervalValues"
/>

如果您只想显示每个字段的纯文本值作为摘要,那么下面的代码应该是最容易维护的。它只需要两处更改(第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);
}


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

以下是我的解决方案:

构建一个首选项类型“getter”方法。

protected String getPreference(Preference x) {
// http://stackoverflow.com/questions/3993982/how-to-check-type-of-variable-in-java
if (x instanceof CheckBoxPreference)
return "CheckBoxPreference";
else if (x instanceof EditTextPreference)
return "EditTextPreference";
else if (x instanceof ListPreference)
return "ListPreference";
else if (x instanceof MultiSelectListPreference)
return "MultiSelectListPreference";
else if (x instanceof RingtonePreference)
return "RingtonePreference";
else if (x instanceof SwitchPreference)
return "SwitchPreference";
else if (x instanceof TwoStatePreference)
return "TwoStatePreference";
else if (x instanceof DialogPreference) // Needs to be after ListPreference
return "DialogPreference";
else
return "undefined";
}

构建一个'setSummaryInit'方法。

public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
Log.i(TAG, "+ onSharedPreferenceChanged(prefs:" + prefs + ", key:" + key + ")");
if( key != null ) {
updatePreference(prefs, key);
setSummary(key);
} else {
Log.e(TAG, "Preference without key!");
}
Log.i(TAG, "- onSharedPreferenceChanged()");
}


protected boolean setSummary() {
return _setSummary(null);
}
    

protected boolean setSummary(String sKey) {
return _setSummary(sKey);
}
    

private boolean _setSummary(String sKey) {
if (sKey == null) Log.i(TAG, "Initializing");
else Log.i(TAG, sKey);
        

// Get Preferences
SharedPreferences sharedPrefs = PreferenceManager
.getDefaultSharedPreferences(this);


// Iterate through all Shared Preferences
// http://stackoverflow.com/questions/9310479/how-to-iterate-through-all-keys-of-shared-preferences
Map<String, ?> keys = sharedPrefs.getAll();
for (Map.Entry<String, ?> entry : keys.entrySet()) {
String key = entry.getKey();
// Do work only if initializing (null) or updating specific preference key
if ( (sKey == null) || (sKey.equals(key)) ) {
String value = entry.getValue().toString();
Preference pref = findPreference(key);
String preference = getPreference(pref);
Log.d("map values", key + " | " + value + " | " + preference);
pref.setSummary(key + " | " + value + " | " + preference);
if (sKey != null) return true;
}
}
return false;
}


private void updatePreference(SharedPreferences prefs, String key) {
Log.i(TAG, "+ updatePreference(prefs:" + prefs + ", key:" + key + ")");
Preference pref = findPreference(key);
String preferenceType = getPreference(pref);
Log.i(TAG, "preferenceType = " + preferenceType);
Log.i(TAG, "- updatePreference()");
}

初始化

创建一个公共类PreferenceActivity并实现OnSharedPreferenceChangeListener

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceManager.setDefaultValues(this, R.xml.global_preferences,
false);
this.addPreferencesFromResource(R.xml.global_preferences);
this.getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}


protected void onResume() {
super.onResume();
setSummary();
}

如果你使用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"));
}
}
这里,所有这些都是从Eclipse样本SettingsActivity中截取的。 我不得不复制所有这些太多的代码,以显示这些android开发人员如何完美地选择更通用和稳定的编码风格。

我留下了适应PreferenceActivity到平板电脑和更大的API的代码。

public class SettingsActivity extends PreferenceActivity {


@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);


setupSummaryUpdatablePreferencesScreen();
}


private void setupSummaryUpdatablePreferencesScreen() {


// In the simplified UI, fragments are not used at all and we instead
// use the older PreferenceActivity APIs.


// Add 'general' preferences.
addPreferencesFromResource(R.xml.pref_general);


// Bind the summaries of EditText/List/Dialog preferences to
// their values. When their values change, their summaries are updated
// to reflect the new value, per the Android Design guidelines.
bindPreferenceSummaryToValue(findPreference("example_text"));
bindPreferenceSummaryToValue(findPreference("example_list"));
}


/**
* A preference value change listener that updates the preference's summary
* to reflect its new value.
*/
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {


private String TAG = SettingsActivity.class.getSimpleName();


@Override
public boolean onPreferenceChange(Preference preference, Object value) {
String stringValue = value.toString();


if (preference instanceof ListPreference) {
// For list preferences, look up the correct display value in
// the preference's 'entries' list.
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(stringValue);


// Set the summary to reflect the new value.
preference.setSummary(
index >= 0
? listPreference.getEntries()[index]
: null);
} else {
// For all other preferences, set the summary to the value's
// simple string representation.
preference.setSummary(stringValue);
}
Log.i(TAG, "pref changed : " + preference.getKey() + " " + value);
return true;
}
};


/**
* Binds a preference's summary to its value. More specifically, when the
* preference's value is changed, its summary (line of text below the
* preference title) is updated to reflect the value. The summary is also
* immediately updated upon calling this method. The exact display format is
* dependent on the type of preference.
*
* @see #sBindPreferenceSummaryToValueListener
*/


private static void bindPreferenceSummaryToValue(Preference preference) {
// Set the listener to watch for value changes.
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);


// Trigger the listener immediately with the preference's
// current value.
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.getContext())
.getString(preference.getKey(), ""));
}


}

xml/pref_general.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >


<!-- NOTE: EditTextPreference accepts EditText attributes. -->
<!-- NOTE: EditTextPreference's summary should be set to its value by the activity code. -->
<EditTextPreference
android:capitalize="words"
android:defaultValue="@string/pref_default_display_name"
android:inputType="textCapWords"
android:key="example_text"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/pref_title_display_name" />


<!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog todismiss it.-->
<!-- NOTE: ListPreference's summary should be set to its value by the activity code. -->
<ListPreference
android:defaultValue="-1"
android:entries="@array/pref_example_list_titles"
android:entryValues="@array/pref_example_list_values"
android:key="example_list"
android:negativeButtonText="@null"
android:positiveButtonText="@null"
android:title="@string/pref_title_add_friends_to_messages" />


</PreferenceScreen>

values/strings_activity_settings.xml

<resources>
<!-- Strings related to Settings -->


<!-- Example General settings -->


<string name="pref_title_display_name">Display name</string>
<string name="pref_default_display_name">John Smith</string>


<string name="pref_title_add_friends_to_messages">Add friends to messages</string>
<string-array name="pref_example_list_titles">
<item>Always</item>
<item>When possible</item>
<item>Never</item>
</string-array>
<string-array name="pref_example_list_values">
<item>1</item>
<item>0</item>
<item>-1</item>
</string-array>
</resources>

注意:实际上我只是想评论像“谷歌的PreferenceActivity的样本也很有趣”。但我的声望值不够。所以请不要怪我

(抱歉我的英语不好)

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

也许像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());
}
}

在你的xml中使用这个:

<your.package.EditTextPreference
android:key="pref_alpha"
android:summary="Actual value: %s"
android:title="Title"
android:defaultValue="default"
/>

因此,你可以用%s而不是实际值来编写摘要。

如果有人还在寻找这个问题的答案,你应该检查thirtythreefortys的答案。

<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的选择器显示的那样。

简单:

listPreference.setSummary("%s");

仅供参考:

findPreference(CharSequence key)
This method was deprecated in API level 11. This function is not relevant
for a modern fragment-based PreferenceActivity.

更有理由看看上面的@ASD的非常巧妙的Answer (来源:),它表示在android:summary中对preferences.xml中的每个字段使用%s。(首选项的当前值被替换为%s。)

enter image description here

<ListPreference
...
android:summary="Length of longest word to return as match is %s"
...
/>

你必须在onCreate方法上使用bindPreferenceSummaryToValue函数。

例子:

    @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add 'general' preferences, defined in the XML file
addPreferencesFromResource(R.xml.pref_general);


// For all preferences, attach an OnPreferenceChangeListener so the UI summary can be
// updated when the preference changes.
bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_location_key)));
bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_units_key)));
}

参见Udacity Android课程:https://www.udacity.com/course/viewer !/ c-ud853 / l - 1474559101 / e - 1643578599 / m - 1474559101上的第3课

EditTextPreference:

我来到这个解决方案,当然,只是如果你需要特定的edittextpreference,但你可以这样做,每一个偏好:

............

private static final String KEY_EDIT_TEXT_PREFERENCE2 = "on_a1";
public static  String value = "";

............

private void updatePreference(Preference preference, String key) {


if (key.equals(KEY_EDIT_TEXT_PREFERENCE2)) {
preference = findPreference(key);
if (preference instanceof EditTextPreference) {
editTextPreference = (EditTextPreference) preference;
editTextPreference.setSummary(editTextPreference.getText());
value = editTextPreference.getText().toString();
return;
}
SharedPreferences sharedPrefs = getPreferenceManager().getSharedPreferences();
preference.setSummary(sharedPrefs.getString(KEY_EDIT_TEXT_PREFERENCE2, ""));


}
}

然后在onResume();

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


SharedPreferences etext = getPreferenceManager().getSharedPreferences();
String str = etext.getString("value", "");
editTextPreference = (EditTextPreference) findPreference(KEY_EDIT_TEXT_PREFERENCE2);
editTextPreference.setText(str);
editTextPreference.setSummary(editTextPreference.getText());


getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}

:

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
updatePreference(findPreference(key), key);
}

我的解决方案是创建一个自定义的EditTextPreference,在XML中像这样使用:<com.example.EditTextPreference android:title="Example Title" />

EditTextPreference.java: -

package com.example;


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


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


setSummary(getSummary());
}


@Override
public CharSequence getSummary()
{
return getText();
}
}

下面是基于@tdeveaux answer的PreferenceFragment中所有__abc0的工作解决方案:

public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "SettingsFragment";


@Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}


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


for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); ++i) {
Preference preference = getPreferenceScreen().getPreference(i);
updatePreference(preference);
}
}


@Override
public void onSharedPreferenceChanged (SharedPreferences sharedPreferences, String key) {
updatePreference(findPreference(key));
}


private void updatePreference (Preference preference) {
if (preference instanceof EditTextPreference) {
EditTextPreference editTextPreference = (EditTextPreference)preference;
editTextPreference.setSummary(editTextPreference.getText());
}
}
}

因为我使用的是自定义PreferenceDataStore,所以我不能向某个SharedPreference添加侦听器,所以我不得不编写一个有点笨拙的解决方案来侦听每个首选项:

class SettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener {
private val handler: Handler by lazy { Handler(Looper.getMainLooper()) }


override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
preferenceManager.preferenceDataStore = prefs
addPreferencesFromResource(R.xml.app_preferences)
onPreferenceChange(preferenceScreen, null)
}


override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
preference.onPreferenceChangeListener = this


when (preference) {
is PreferenceGroup -> for (i in 0 until preference.preferenceCount) {
onPreferenceChange(preference.getPreference(i), null)
}
is ListPreference -> {
if (preference.value == null) {
preference.isPersistent = false
preference.value = Preference::class.java.getDeclaredField("mDefaultValue")
.apply { isAccessible = true }
.get(preference).toString()
preference.isPersistent = true
}


postPreferenceUpdate(Runnable { preference.summary = preference.entry })
}
}
return true
}


/**
* We can't directly update the preference summary update because [onPreferenceChange]'s result
* is used to decide whether or not to update the pref value.
*/
private fun postPreferenceUpdate(r: Runnable) = handler.post(r)
}

我发现这种方法可以从支持库句柄"%s"中总结EditTextPreference(因为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" />

简洁的解决方案只需一行代码:

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


bindPreferenceSummaryToValue(findPreference("mySetting"));


// initialize summary
sBindPreferenceSummaryToValueListener.onPreferenceChange(findPreference("mySetting"),
((ListPreference) findPreference("mySetting")).getEntry());
}

由于在androidx首选项类有SummaryProvider接口,它可以在没有OnSharedPreferenceChangeListener的情况下完成。为EditTextPreference和ListPreference提供了简单的实现。在EddieB的回答上构建,它看起来像这样。在androidx.preference上测试:preference:1.1.0-alpha03。

package com.example.util.timereminder.ui.prefs;


import android.os.Bundle;


import com.example.util.timereminder.R;


import androidx.preference.EditTextPreference;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceGroup;


/**
* Displays different preferences.
*/
public class PrefsFragmentExample extends PreferenceFragmentCompat {


@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);


initSummary(getPreferenceScreen());
}


/**
* Walks through all preferences.
*
* @param p The starting preference to search from.
*/
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 {
setPreferenceSummary(p);
}
}


/**
* Sets up summary providers for the preferences.
*
* @param p The preference to set up summary provider.
*/
private void setPreferenceSummary(Preference p) {
// No need to set up preference summaries for checkbox preferences because
// they can be set up in xml using summaryOff and summary On
if (p instanceof ListPreference) {
p.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance());
} else if (p instanceof EditTextPreference) {
p.setSummaryProvider(EditTextPreference.SimpleSummaryProvider.getInstance());
}
}
}

如果你正在使用AndroidX,你可以使用自定义SummaryProvider。此方法可用于任何Preference

来自文档的例子(Java):

EditTextPreference countingPreference = (EditTextPreference) findPreference("counting");


countingPreference.setSummaryProvider(new SummaryProvider<EditTextPreference>() {
@Override
public CharSequence provideSummary(EditTextPreference preference) {
String text = preference.getText();
if (TextUtils.isEmpty(text)){
return "Not set";
}
return "Length of saved value: " + text.length();
}
});

来自文档的例子(Kotlin):

val countingPreference = findPreference("counting") as EditTextPreference


countingPreference.summaryProvider = SummaryProvider<EditTextPreference> { preference ->
val text = preference.text
if (TextUtils.isEmpty(text)) {
"Not set"
} else {
"Length of saved value: " + text.length
}
}

根据安卓系统文档,你可以在ListPreference和EditTextPreference组件中使用app:useSimpleSummaryProvider="true"

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

只需将这一行添加到您的xml规范中。 应用:useSimpleSummaryProvider =“true" < / p >

例如:

& lt; your.package.name.MyListPreference

android:key="noteInterval"
android:defaultValue="60"
android:title="Notification Interval"
android:entries="@array/noteInterval"
android:entryValues="@array/noteIntervalValues"
app:useSimpleSummaryProvider="true"

/比;