EditTextPreference 值仅在第二次单击 ListPreference 后刷新

EditTextPreference value only refreshed after clicking ListPreference second time

我已经为这个问题苦苦挣扎了一段时间,所以我决定在这里问我做错了什么。

首先: - 我有一个 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. 一个 listPreference,其默认值和条目将设置 EditTextPreference 的标题和摘要。
  2. 在 ListPreference 上选择一个项目时,它还会根据所选项目的值和条目更新 EditTextPreference 的标题和摘要。
  3. 不确定如何处理 EditTextPreference。这是你的选择。

我仍然认为您应该考虑制作自定义首选项 class,因为您写道您打算​​使用很多对 ListPreference 和 EditTextPreference。

顺便说一句,代码基于我制作的应用程序 (link here)。我这样做是为了更容易处理多个 listPreferences。

代码如下:

res/values/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/values/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>

res/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;
    }
  }