[英]Change the summary of a ListPreference with the new value (Android)
如何将 ListPreference 的摘要修改为用户选择的新“条目”字符串(不是条目值)
我认为它与 setOnPreferenceChangeListener() 但在
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
return true;
}
}
使用 ((ListPreference)preference).getEntry() 我得到旧值(因为它尚未更改)并且 newValue.toString() 返回条目值(不是显示给用户的条目文本)
我该怎么做? 提前致谢
只需在 xml 描述中将汇总值设置为%s
即可。
编辑:我已经在几台设备上对其进行了测试,但它并没有真正起作用。 这很奇怪,因为根据文档它必须工作: ListPreference.getSummary() 。
但是可以自己实现这个功能。 该实现需要从ListPreference
class 继承:
public class MyListPreference extends ListPreference {
public MyListPreference(final Context context) {
this(context, null);
}
public MyListPreference(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@Override
public CharSequence getSummary() {
final CharSequence entry = getEntry();
final CharSequence summary = super.getSummary();
if (summary == null || entry == null) {
return null;
} else {
return String.format(summary.toString(), entry);
}
}
@Override
public void setValue(final String value) {
super.setValue(value);
notifyChanged();
}
}
如您所见MyListPreference
有自己的汇总字段,可以包含格式标记。 当首选项的值发生变化时,会调用Preference.notifyChanged()
方法,并导致从Preference.onBindView()
调用MyListPreference.getSummary()
方法。
PS:此方法尚未经过充分测试,因此可能包含错误。
%s
实现是错误的。 视图在首次加载时显示正确的值(如果设置了默认列表值),但在选择列表项时视图不会更新。 您必须切换复选框或其他一些偏好来更新视图。
作为一种解决方法,实施OnSharedPreferenceChangeListener
以覆盖列表首选项的摘要。
/src/apps/app_settings/SettingsActivity.java
package apps.app_settings;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class SettingsActivity extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* set fragment */
getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
}
}
/src/apps/app_settings/SettingsFragment.java
package apps.app_settings;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
public class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* set preferences */
addPreferencesFromResource(R.xml.preferences);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
/* get preference */
Preference preference = findPreference(key);
/* update summary */
if (key.equals("list_0")) {
preference.setSummary(((ListPreference) preference).getEntry());
}
}
@Override
public void onResume() {
super.onResume();
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onPause();
}
}
/res/xml/preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:key="list_0"
android:title="@string/settings_list_0_title"
android:summary="%s"
android:entries="@array/settings_list_0_entries"
android:entryValues="@array/settings_list_0_entry_values"
android:defaultValue="@string/settings_list_0_default_value"/>
</PreferenceScreen>
/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="settings_list_0_title">list 0</string>
<string-array name="settings_list_0_entries">
<item>item 0</item>
<item>item 1</item>
<item>item 2</item>
</string-array>
<string-array name="settings_list_0_entry_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<string name="settings_list_0_default_value">0</string>
</resources>
我用另一个简单的解决方案解决了这个问题(https://gist.github.com/brunomateus/5617025) :
public class ListPreferenceWithSummary extends ListPreference{
public ListPreferenceWithSummary(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListPreferenceWithSummary(Context context) {
super(context);
}
@Override
public void setValue(String value) {
super.setValue(value);
setSummary(value);
}
@Override
public void setSummary(CharSequence summary) {
super.setSummary(getEntry());
}
}
这在我的 GirgerBeard 设备上运行良好。 即使是第一次运行您的应用程序。 不要忘记在您的 xml 偏好设置上提供默认值:
android:defaultValue="default value"
并在您的PreferenceActivity
或PrefenceFragment
上设置默认值:
PreferenceManager.setDefaultValues(this, R.xml.you pref file, false);
我建议在您的 PreferenceFragment 或 PreferenceActivity 中实现 OnSharedPreferenceChangeListener 而不是 Preference.setOnPreferenceChangeListner。 使用 setSummay 设置新的更改。 (不要忘记注册和取消注册监听器。)在对首选项的更改完成后调用此监听器。 您还应该在 XML 中为首选项设置默认值。
通过将 %s 直接写入 XML 文件,“%s”解决方案适用于 android 4.0.3。 问题是在我更改了首选项的值后文本没有更新,但是当我修改了我的 PreferenceScreen 的另一个首选项时。 也许这里缺少一些刷新。
这是我实现的最简化的方式。 只需取 onPreferenceChange 监听器给出的值
ListPreference preference;
@Override
protected void onCreate(Bundle savedInstanceState) {
preference = (ListPreference)findPreference("myKey");
preference.setSummary(preferenceColorButtons.getEntry());
preference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
ListPreference listPreference = (ListPreference)preference;
int id = 0;
for (int i = 0; i < listPreference.getEntryValues().length; i++)
{
if(listPreference.getEntryValues()[i].equals(newValue.toString())){
id = i;
break;
}
}
preference.setSummary(listPreference.getEntries()[id]);
return true;
}
});
}
据我所知:
a) %s 确实适用于 android 4,但不适用于 2.x。
b)如果您在两者之间设置一个虚拟值,则可以实现更新,请参见此处: https://stackoverflow.com/a/16397539/1854563
无需扩展 ListPreference 或遍历 entryValues 等
public boolean onPreferenceChange(Preference preference, Object newValue) {
int i = ((ListPreference)preference).findIndexOfValue(newValue.toString());
CharSequence[] entries = ((ListPreference)preference).getEntries();
preference.setSummary(entries[i]);
return true;
}
我知道这是一个非常古老的问题,但它仍然是实际的。 要自动更新摘要,您必须调用原始的preferenceChangeListener:
final OnPreferenceChangeListener listener = preference.getOnPreferenceChangeListener();
preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
{
@Override
public boolean onPreferenceChange(Preference preference, Object o)
{
if (listener !=null)
listener .onPreferenceChange(preference, o);
return true;
}
});
我也遇到了这个问题,我终于通过使用来自侦听器的值找到了解决方案。 在下面的示例中(对于 ListPreference),我首先获取 ListPreference 数组中值的索引,然后使用该索引检索该值的 label:
passwordFrequencyLP.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
int newFrequency = Integer.valueOf(newValue.toString());
prefs.edit().putInt("settings_key_password_frequency", newFrequency).commit();
//get the index of the new value selected in the ListPreference array
int index = passwordFrequencyLP.findIndexOfValue(String.valueOf(newValue));
//get the label of the new value selected
String label = (String) passwordFrequencyLP.getEntries()[index];
passwordFrequencyLP.setSummary(label);
makeToast(getResources().getString(R.string.password_frequency_saved));
return true;
}
});
这个小技巧效果很好,我找到了许多不同的可能解决方案,但只有这个对我有用。
如果有帮助,您好为 EditText 编辑了上述内容:)
package fr.bmigette.crocoschedulerconsoleandroid;
import android.content.Context;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
/**
* Created by bastien on 28/07/2015.
*/
public class EditTextPreferenceWithSummary extends EditTextPreference{
public EditTextPreferenceWithSummary(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextPreferenceWithSummary(Context context) {
super(context);
}
@Override
public void setText(String value) {
super.setText(value);
setSummary(value);
}
@Override
public void setSummary(CharSequence summary) {
super.setSummary(getText());
}
}
并像这样创建preference.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:key="pref_key_category_host"
android:title="@string/title_category_host" >
<fr.bmigette.crocoschedulerconsoleandroid.EditTextPreferenceWithSummary
android:defaultValue="@string/default_pref_host_1"
android:key="pref_key_host_1"
android:summary="@string/default_pref_host_1"
android:title="@string/title_pref_host_1" />
<fr.bmigette.crocoschedulerconsoleandroid.EditTextPreferenceWithSummary
android:defaultValue="@string/default_pref_port_1"
android:key="pref_key_port_1"
android:summary="@string/default_pref_port_1"
android:title="@string/title_pref_port_1" />
<fr.bmigette.crocoschedulerconsoleandroid.EditTextPreferenceWithSummary
android:defaultValue="@string/default_pref_pass_1"
android:key="pref_key_pass_1"
android:summary="@string/default_pref_pass_1"
android:title="@string/title_pref_pass_1" />
</PreferenceCategory>
</PreferenceScreen>
无需进行那些额外的编码,我已经遇到了这个问题并通过一行解决了它。
经过数小时查看此问题和其他类似问题的所有答案后,我发现了无需扩展ListPreference
的最简单方法,您可以共同extends PreferenceActivity
,请参见下面的代码。
public class UserSettingsActivity extends PreferenceActivity
{
ListPreference listpref;
@Override
public void onCreate(Bundle savedInstenceState)
{
super.onCreate(savedInstenceState);
addPreferencesFromResource(R.xml.settings);
listpref = (ListPreference)findPreference("prefDefaultCurrency");
listpref.setOnPreferenceChangeListener(new OnPreferenceChangeListener()
{
@Override
public boolean onPreferenceChange(Preference preference, Object value) {
// TODO Auto-generated method stub
listpref.setSummary(listpref.getEntries()[Integer.parseInt(value.toString())]);
return true;
}
});
就是这样,只需一行,您所要做的就是获取从onPreferenceChange(Preference preference, Object value)
传递的值,将其解析为 integer 并将其传递给listpref.setSummary(listpref.getEntries()[Integer.parseInt(value.toString())]);
参考接受的答案 (@Michael),如果您修改 MyListPreference 以添加 onPreferenceChangeListener:
public MyListPreference(final Context context, final AttributeSet attrs) {
super(context, attrs);
setOnPreferenceChangeListener(this);
}
并让监听器实现返回 true:
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Do other stuff as needed, e.g. setTitle()
return true;
}
摘要“%s”始终解析为最新设置。 否则,它始终具有默认设置。
不要忘记添加工具:
public class MyListPreference extends ListPreference implements Preference.OnPreferenceChangeListener
Kotlin 中最简单的方法
findPreference<ListPreference>(getString(R.string.pref_some_key)).apply {
summary = entry
setOnPreferenceChangeListener { _, newValue ->
summary = entries[entryValues.indexOf(newValue)]
return@setOnPreferenceChangeListener true
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.