[英]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.