Измените резюме ListPreference с новым значением (Android)
Как изменить сводку ListPreference на новую строку "Enter", выбранную пользователем (а не значение записи)
Я поддерживаю его с помощью setOnPreferenceChangeListener(), но в
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
return true;
}
}
используя ((предпочтение ListPreference)).getEntry() Я получаю старое значение (потому что оно еще не изменено), а newValue.toString() возвращает значение записи (а не текст ввода, отображаемый пользователю)
Как я могу это сделать? Спасибо заранее
Ответы
Ответ 1
Просто установите итоговое значение %s
в описании xml.
EDIT. Я тестировал его на нескольких устройствах, и он не работает. Это странно, потому что согласно документам он должен работать: ListPreference.getSummary().
Но возможно реализовать эту функциональность самим собой. Для реализации требуется наследовать класс ListPreference
:
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()
и вызывает метод MyListPreference.getSummary()
для вызова из Preference.onBindView()
.
P.S.: Этот подход недостаточно проверен, поэтому он может содержать ошибки.
Ответ 2
Нуман Зубайр прав.
Реализация %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>
Ответ 3
Я решил эту проблему другим и простым решением (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);
Ответ 4
Я рекомендую реализовать OnSharedPreferenceChangeListener в вашем PreferenceFragment или PreferenceActivity вместо Preference.setOnPreferenceChangeListner. Используйте setSummay для установки новых изменений. (Не забудьте зарегистрировать и отменить регистрацию слушателя.) Этот слушатель вызывается после того, как изменение в предпочтении было завершено. Вы также должны установить значение по умолчанию в XML для предпочтений.
Ответ 5
Решение "% s" работает для меня на android 4.0.3, набрав% s непосредственно в файле XML. Проблема заключается в том, что текст не обновляется после того, как я изменил значение предпочтения, но это когда я изменяю другое предпочтение моего PreferenceScreen. Возможно, некоторые обновления отсутствуют здесь.
Ответ 6
Это самый упрощенный способ, который я реализовал. Просто возьмите значения, заданные слушателем 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;
}
});
}
Ответ 7
Все, что я знаю:
a)% s работает на android 4, но не на 2.x.
b) Обновление достигается, если вы установите значение фиктивного значения в промежутке, см. здесь: fooobar.com/questions/16930/...
Ответ 8
Нет необходимости расширять 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;
}
Ответ 9
Я знаю, что это очень старый вопрос, но он по-прежнему актуальный.
Чтобы автоматически обновить сводку, вы должны вызвать исходную функцию предпочтенияChangeListener:
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;
}
});
Ответ 10
Я также столкнулся с этой проблемой, и я, наконец, нашел решение, используя значение, исходящее от слушателя.
В моем примере ниже (для ListPreference) я сначала получаю индекс значения в массиве ListPreference, затем я извлекаю метку значения с помощью этого индекса:
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;
}
});
Этот небольшой трюк работает хорошо, я нашел много разных возможных решений этой проблемы, но только этот работал у меня.
Ответ 11
Hi отредактировал выше для 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>
Ответ 12
Нет необходимости делать это дополнительное кодирование, я столкнулся с этой проблемой и решил его одной строкой.
После многих часов, рассматривающих все ответы в этом и других подобных вопросах, я обнаружил самый простой способ сделать это без расширения 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)
, разделить его на целое и передать его на listpref.setSummary(listpref.getEntries()[Integer.parseInt(value.toString())]);
Ответ 13
Ссылаясь на принятый ответ (@Michael), если вы изменяете MyListPreference, чтобы добавить onPreferenceChangeListener:
public MyListPreference(final Context context, final AttributeSet attrs) {
super(context, attrs);
setOnPreferenceChangeListener(this);
}
а реализация listener возвращает 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