user-interface - 如何显示属性当前值?

  显示原文与译文双语对照的内容

这必须经常出现。

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

示例:如果我有一个"丢弃旧信件"首选项设置,指定需要清除消息的天数。 在 PreferenceActivity 中,我希望用户看到:

"丢弃旧信件" <——标题

"在天后清除邮件"<- 摘要,其中是当前首选值

额外的信用:让这个可以重用,所以我可以轻松地将它应用到所有的偏好,而不管它们的类型( 这样就可以使用 EditTextPreference,ListPreference 等等,最少的编码量) 。

时间:

如果满足你的需求,有一些方法可以使这个解决方案更加通用。

例如如果你想将所有列表首选项显示为摘要,你可以将它的用于 onSharedPreferenceChanged 实现:


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

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

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

和使用 getPreferenceCountPreferenceScreenPreferenceCategorygetPreference 功能,你可以轻松地编写一个通用函数走树偏好设置的所有偏好类型的总结你渴望他们 toString 表示

这是我的解决方案。。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().contains("assword"))
 {
 p.setSummary("******");
 } else {
 p.setSummary(editTextPref.getText());
 }
 }
 if (p instanceof MultiSelectListPreference) {
 EditTextPreference editTextPref = (EditTextPreference) p;
 p.setSummary(editTextPref.getText());
 }
 }
}

如果你使用 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) {
 updatePreference(preferenceGroup.getPreference(j));
 }
 } else {
 updatePreference(preference);
 }
 }
 }

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

 private void updatePreference(Preference preference) {
 if (preference instanceof ListPreference) {
 ListPreference listPreference = (ListPreference) preference;
 listPreference.setSummary(listPreference.getEntry());
 }
 }
 }

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

文档 。说可以在 getSummary() 中使用字符串格式标记:

如果摘要中有字符串格式标记( 例如 。 "%s"或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或或者或"%1$s"),那么当前的输入值将替换为它的位置。

仅指定 android:summary="Clean up messages after %s days" 在为我工作的ListPreference xml声明中。

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

[ 更新:最终版本列表]


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

你可以覆盖默认首选项类并实现功能。


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

稍后,你可以使用自定义首选项,比如


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

这是你需要将摘要设置为所选值的代码。 它还设置启动时的值并尊重默认值,而不仅仅是更改。 只需将" r.layout.prefs"更改为你的xml-file,并将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

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

感谢你的提示 !

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

这是我现在的方式:


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

这对我来说很有用,但我想知道什么是最好的解决方案( 性能,稳定性,scalibility ): 一个Koem显示或者这个?

...