Значение EditTextPreference обновляется только после повторного нажатия ListPreference

Я уже давно борюсь с этой проблемой, поэтому решил спросить здесь, что я делаю не так.

Прежде всего: - у меня есть PreferenceFragment с ListPreference вверху и EditTextPreference ниже - ListPreference заполнен объектами, значения хранятся в файле и считываются оттуда (это работает без нареканий) - EditTextPreference должно отображать значение в ListPreference выбранный объект. И это проблема: после выбора значения ничего не меняется, поэтому я должен нажать на ListPreference еще раз, и значение установлено правильно. Это проблема с моим слушателем?

Вот код:

public class SettingsTestFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {

    private final String[] pref_key_array = {"pref_key_lp", "pref_key_et""}; // array that contains all the preference keys of changeable values
    private final int numberOfEntries = pref_key_array.length;
    private Preference[] pref_entries;
    String[] entries = {"Value 1", "Value 2", "Value 3"};
    String[] entryValues = {"0", "1", "2"};
    private int position;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
        final SharedPreferences myPreference = PreferenceManager.getDefaultSharedPreferences(getActivity());

        final EditTextPreference et = (EditTextPreference) findPreference("pref_key_et");
        final ListPreference lp = (ListPreference) findPreference("pref_key_lp");
        prepareListPref(lp);
        pref_entries = new Preference[numberOfEntries];
        for(int i = 0; i < numberOfEntries; i++) {
            pref_entries[i] = getPreferenceScreen().findPreference(pref_key_array[i]);
        }


        lp.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                position = Integer.valueOf(myPreference.getString("pref_key_lp", "0"));
                et.setText(entries[position]);
                return true;
            }
        });


        Preference.OnPreferenceChangeListener changeListener = new Preference.OnPreferenceChangeListener() {
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                position = Integer.valueOf(myPreference.getString("pref_key_lp", "0"));
                preference.setSummary(entries[position]);
                return true;
            }
        };
         lp.setOnPreferenceChangeListener(changeListener);
    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
       updateSummary(key, pref_key_array, numberOfEntries, pref_entries);
    }


    @Override
    public void onResume() {
        super.onResume();
        // Set up listener when a key changes
        for(int i = 0; i < numberOfEntries; i++) {
            updateSummary(pref_key_array[i], pref_key_array, numberOfEntries, pref_entries);
        }
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        // Unregister listener every time a key changes
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }

    public void prepareListPref(ListPreference lp) {
        lp.setEntries(entries);
        lp.setEntryValues(entryValues);
        lp.setDefaultValue("0");
    }

    public void updateSummary(String key, String[] pref_key_array, int numberOfEntries, Preference[] pref_entries) {
        for(int i = 0; i < numberOfEntries; i++) {
            if(key.equals(pref_key_array[i])) {
                if(pref_entries[i] instanceof EditTextPreference) {
                    final EditTextPreference currentPreference = (EditTextPreference) pref_entries[i];
                    pref_entries[i].setSummary(currentPreference.getText());
                } else if(pref_entries[i] instanceof ListPreference) {
                    final ListPreference currentPreference = (ListPreference) pref_entries[i];
                    pref_entries[i].setSummary(currentPreference.getEntry());
                }
                break;
            }
        }
    }
}

Суммирование кода для чтения из файла и записи значения в Настройки работает, но только после повторного нажатия на ListPreference. У тебя есть идеи почему?

Спасибо

1 ответ

Решение

Хорошо, я не уверен, что вы пытаетесь сделать и в чем проблема, поэтому я сделал пример, показывающий следующее:

  1. a listPreference, что его значение и запись по умолчанию будут устанавливать заголовок и сводку EditTextPreference.
  2. при выборе элемента в ListPreference он также обновляет заголовок и сводку EditTextPreference в соответствии со значением и записью выбранного элемента.
  3. Не уверен, что делать с EditTextPreference. Это твой выбор.

Я все еще думаю, что вам следует подумать о создании пользовательского класса Preference, поскольку вы написали, что намереваетесь использовать множество пар ListPreference&EditTextPreference.

Кстати, код основан на приложении, которое я сделал (ссылка здесь). Я сделал это так, что будет легко обрабатывать несколько listPreferences.

Вот код:

RES / значения /strings_activity_settings.xml

<resources>

    <string name="pref__custom_app_theme" translatable="false">pref__custom_app_theme</string>
    <string name="pref__app_theme" translatable="false">pref__app_theme</string>

    <string-array name="pref__app_theme_entries">
        <item>@string/cards_light</item>
        <item>@string/cards_dark</item>
    </string-array>

    <string name="pref__app_theme__cards_ui" translatable="false">CARDS_UI</string>
    <string name="pref__app_theme__cards_ui_dark" translatable="false">CARDS_UI_DARK</string>
    <string name="pref__app_theme_default" translatable="false">@string/pref__app_theme__cards_ui</string>


    <string-array name="pref__app_theme_values">
        <item>@string/pref__app_theme__cards_ui</item>
        <item>@string/pref__app_theme__cards_ui_dark</item>
    </string-array>
</resources>

RES / значения /strings.xml

<resources>
    <string name="app_name">My Application</string>

    <string name="app_theme">App Theme</string>
    <string name="cards_light">cards light</string>
    <string name="cards_dark">cards dark</string>
</resources>

Рез / XML / pref_general.xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- theme -->
    <ListPreference
        android:defaultValue="@string/pref__app_theme_default"
        android:entries="@array/pref__app_theme_entries"
        android:entryValues="@array/pref__app_theme_values"
        android:key="@string/pref__app_theme"
        android:title="@string/app_theme"/>

    <EditTextPreference android:key="@string/pref__custom_app_theme"/>
</PreferenceScreen>

SettingsActivity.java

public class SettingsActivity extends PreferenceActivity
  {
  public interface IOnListPreferenceChosenListener
    {
    public void onChosenPreference(String key,String entry,String value);
    }

  @SuppressWarnings("deprecation")
  @Override
  protected void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.pref_general);
    final EditTextPreference editTextPreference=(EditTextPreference)findPreference(getString(R.string.pref__custom_app_theme));
    final ListPreference listPreference=prepareListPreference(this,R.string.pref__app_theme,R.array.pref__app_theme_entries,R.array.pref__app_theme_values,R.string.pref__app_theme_default,new IOnListPreferenceChosenListener()
      {
        @Override
        public void onChosenPreference(final String key,final String entry,final String value)
          {
          editTextPreference.setTitle(value);
          editTextPreference.setSummary(entry);
          }
      });
    editTextPreference.setTitle(listPreference.getValue());
    editTextPreference.setSummary(listPreference.getEntry());
    }

  public static ListPreference prepareListPreference(final PreferenceActivity activity,final int prefKeyId,//
      final int entriesId,final int valuesId,final int defaultValueId,final IOnListPreferenceChosenListener listener)
    {
    final String prefKey=activity.getString(prefKeyId);
    @SuppressWarnings("deprecation")
    final ListPreference pref=(ListPreference)activity.findPreference(prefKey);
    final String[] entries=activity.getResources().getStringArray(entriesId);
    final String[] values=activity.getResources().getStringArray(valuesId);
    final String defaultValue=activity.getResources().getString(defaultValueId);
    final String currentValue=PreferenceManager.getDefaultSharedPreferences(activity).getString(prefKey,defaultValue);
    for(int i=0;i<values.length;++i)
      {
      final String value=values[i];
      if(TextUtils.equals(currentValue,value))
        {
        pref.setSummary(entries[i]);
        pref.setValueIndex(i);
        break;
        }
      }
    pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener()
      {
        @Override
        public boolean onPreferenceChange(final Preference preference,final Object newValue)
          {
          final String newValueStr=newValue.toString();
          String entryChosen=null;
          for(int i=0;i<values.length;++i)
            {
            final String value=values[i];
            if(TextUtils.equals(newValueStr,value))
              {
              entryChosen=entries[i];
              break;
              }
            }
          pref.setSummary(entryChosen);
          if(listener!=null)
            listener.onChosenPreference(prefKey,entryChosen,newValueStr);
          return true;
          }
      });
    return pref;
    }
  }
Другие вопросы по тегам