这必须经常出现。
当用户在Android应用中编辑偏好设置时,我希望他们能够在Preference
摘要中查看当前设置的偏好设置值。
示例:如果我有“丢弃旧邮件”的“首选项”设置,该设置指定需要清除邮件的天数。在PreferenceActivity
我希望用户看到:
“弃掉旧邮件”< - title
“在 x 天之后清理消息”< - summary其中 x 是当前的偏好值
额外功劳:使其可重复使用,因此无论其类型如何,我都可以轻松地将其应用于我的所有首选项(以便使用EditTextPreference,ListPreference等,只需最少的编码)。
答案 0 :(得分:151)
如果符合您的需求,有很多方法可以将其作为更通用的解决方案。
例如,如果您希望所有列表首选项都显示其选择为摘要,则可以将此选项用于onSharedPreferenceChanged
实现:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = findPreference(key);
if (pref instanceof ListPreference) {
ListPreference listPref = (ListPreference) pref;
pref.setSummary(listPref.getEntry());
}
}
这很容易扩展到其他偏好类。
通过使用getPreferenceCount
和getPreference
中的PreferenceScreen
和PreferenceCategory
功能,您可以轻松编写一个通用函数来遍历首选项树设置所有首选项的摘要您希望toString
代表
答案 1 :(得分:141)
这是我的解决方案...... 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());
}
}
}
答案 2 :(得分:90)
Android documentation表示可以在getSummary()
中使用字符串格式标记:
如果摘要中包含字符串格式标记(即“%s”或“%1 $ s”),则当前条目值将替换为其位置。
只需在ListPreference xml声明中指定android:summary="Clean up messages after %s days"
即可。
注意:这仅适用于ListPreference
。
答案 3 :(得分:81)
如果您使用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"));
}
}
答案 4 :(得分:32)
我的选择是扩展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"/>
答案 5 :(得分:23)
您可以覆盖默认的偏好类并实现该功能。
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"
/>
答案 6 :(得分:21)
经过几个小时,我已经花了很多时间来解决这个问题,我已经实现了这个代码:
[更新:最终版本列表]
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”之前。两者都没有。
答案 7 :(得分:18)
这是将摘要设置为所选值所需的代码。它还会在启动时设置值并遵循默认值,而不仅仅是更改时。只需将“R.layout.prefs”更改为您的xml文件,并将setSummary-method扩展到您的需要。它实际上只处理ListPreferences,但它很容易自定义以尊重其他首选项。
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
答案 8 :(得分:18)
也许像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
而不是实际值来撰写摘要。
答案 9 :(得分:11)
实际上,CheckBoxPreference可以根据复选框值指定不同的摘要。查看android:summaryOff和android:summaryOn属性(以及相应的CheckBoxPreference方法)。
答案 10 :(得分:11)
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 :(得分:8)
如果有人仍在寻找答案,您应该查看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将使用首选项的当前字符串值替换%s,如ListPreference的选择器所示。
答案 12 :(得分: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正在展示还是这个?
答案 13 :(得分: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)
干杯,
克里斯
答案 14 :(得分: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;
}
}
答案 15 :(得分: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之间对我工作正常。
答案 16 :(得分:4)
我已经看到所有投票的答案显示如何使用确切的当前值设置摘要,但OP也希望如下:
“在 x 天后”清理消息*&lt; - 摘要 x 是当前的偏好值
以下是我实现
的答案正如documentation所说ListPreference.getSummary()
:
返回此ListPreference的摘要。如果摘要中有一个字符串格式标记(即“%s”或“%1 $ s”),那么当前 入门价将取代它。
但是,我尝试了几种设备,似乎没有用。通过一些研究,我在this answer找到了一个很好的解决方案。它只是扩展您使用的每个Preference
并覆盖getSummary()
以按照Android文档的规定工作。
答案 17 :(得分:3)
这是我的解决方案:
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";
}
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();
}
答案 18 :(得分:3)
如果您只想将每个字段的纯文本值显示为摘要,则以下代码应该是最容易维护的。它只需要两次更改(第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);
}
}
答案 19 :(得分:3)
简单地:
listPreference.setSummary("%s");
答案 20 :(得分:3)
供参考:
findPreference(CharSequence key)
This method was deprecated in API level 11. This function is not relevant
for a modern fragment-based PreferenceActivity.
更有理由查看上面Answer
以上@ %s
非常流畅的android:summary
说preferences.xml
%s
<ListPreference
...
android:summary="Length of longest word to return as match is %s"
...
/>
<header class="site-header">
<nav class="site-nav">
<ul><h4>
<li><a href="index.php"><img src="/inc/menubutton.png" style="width:25px; height: 25px;"></a></li>
<li><form name="search" method="post" action="searchresults.php"></li>
<li><input type="text" class="searchbar" value="Search" style="width:400px;"></li>
<li><input type="image" class="searchbutton" src="inc/searchbutton.png" alt="Submit Form" style="height: 25px; width: 25px;"></li>
</form>
<li><a href="member.php"><img src="inc/ Memberbutton.png" style="width:25px; height:25px;"></a></li>
<li><a href="cart.php"><img src="inc/cart.png" style="width:25px; height:25px;"></a></li>
</ul></h4>
</nav>
}}。 (偏好的当前值代替.site-nav ul {
margin: 0;
padding-left: 20px;
background-color: black;
.site-nav ul:before, .site-nav:after {content: ""; display: table; }
.site-nav ul:after {clear:both; }
.site-nav ul { *zoom: 1; }
.site-nav ul li {
list-style: none;
float: left;
padding: 10px;
。)
// This program reads data from a file into an array.
#include <iostream>
#include <fstream> // To use ifstream
using namespace std;
int main()
{
const int ARRAY_SIZE = 10; // Array size
int numbers[ARRAY_SIZE]; // Array number with 10 elements
int count = 0; // Loop counter variable
ifstream inputFile; // Input file stream object
// Open the file.
inputFile.open("TenNumbers.rtf");
// Read the numbers from the file into the array.
while (count < ARRAY_SIZE && inputFile >> numbers[count]){
count++;
}
// Close the file.
inputFile.close();
// Display the numbers read:
cout << "The numbers are: ";
for (count = 0; count < ARRAY_SIZE; count++){
cout << numbers[count] << " ";
}
cout << endl;
return 0;
}
答案 21 :(得分:2)
由于androidx中的Preference类具有SummaryProvider接口,因此无需OnSharedPreferenceChangeListener即可完成。提供了EditTextPreference和ListPreference的简单实现。在EddieB's answer上构建,它看起来可能像这样。在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());
}
}
}
答案 22 :(得分:2)
在这里,所有这些都是从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>
注意:其实我只是想评论“Google的PreferenceActivity示例也很有趣”。但是我没有足够的声望点。所以请不要怪我。
(抱歉英文不好)
答案 23 :(得分:2)
我的解决方案是创建一个自定义CONST
,在XML中使用如下:EditTextPreference
<强> EditTextPreference.java 强>: -
<com.example.EditTextPreference android:title="Example Title" />
答案 24 :(得分:2)
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);
}
答案 25 :(得分:2)
你必须在onCreate方法上使用bindPreferenceSummaryToValue函数。
示例:
P {color:black !important; font-size: 16pt !important;}
请参阅关于Udacity Android课程的第3课:https://www.udacity.com/course/viewer#!/c-ud853/l-1474559101/e-1643578599/m-1643578601
答案 26 :(得分:1)
因为我使用的是自定义PreferenceDataStore
,所以我无法为某些SharedPreference
添加一个监听器,因此我必须编写一个有点讨厌每个首选项的hacky解决方案:
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)
}
答案 27 :(得分:1)
要将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());
}
}
并引用yourpackage.ListPreference
中的preferences.xml
对象,记住指定android:defaultValue
,因为这会触发对onSetInitialValue()
的调用。
如果您愿意,可以在调用setSummary()
之前修改文本,以适合您的应用程序。
答案 28 :(得分:0)
以下是基于@tdeveaux答案的EditTextPreference
内所有PreferenceFragment
的工作解决方案:
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());
}
}
}
答案 29 :(得分:0)
我发现这样就可以在摘要中从支持库句柄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" />
答案 30 :(得分:0)
如果您使用的是AndroidX,则可以use a custom 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
}
}
答案 31 :(得分:0)
根据Android docs,您可以在ListPreference和EditTextPreference组件中使用app:useSimpleSummaryProvider="true"
。
答案 32 :(得分:0)
在Android Studio中,打开“ root_preferences.xml”,然后选择“设计”模式。选择所需的EditTextPreference首选项,然后在“所有属性”下查找“ useSimpleSummaryProvider”属性并将其设置为true。然后将显示当前值。
答案 33 :(得分:-1)
1行代码的简洁解决方案:
@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());
}