EditTextPreference.setText(значение) не обновляется должным образом

Я пытаюсь запретить пользователю вводить пустую строку в EditTextPreference (в примере catName). Я использую OnPreferenceChangeListener чтобы определить, когда внесены изменения в EditTextPreferenceи если есть изменение и строка пуста, я использую EditTextPreference.setText() Команда для сброса к старому значению. Тем не менее, новое значение не отображается должным образом, если я снова открываю EditTextPreference в графическом интерфейсе (строка пуста), и если я вернусь в основное приложение, я могу убедиться, что пустое значение сохраняется в настройках.

Я проверил, что оператор if выполняется должным образом, и что мой параметр отслеживает старое имя (oldCatName) обновляется, как и ожидалось. Я могу даже войти catName.getText() значение прямо перед setOnPreferenceChangeListener заканчивает выполнение, и я всегда вижу ожидаемое мной значение (новое значение, установленное пользователем, и когда они вводят пустое значение, оно правильно сбрасывается к старому значению). Я не уверен, почему установка значения на EditTextPreference не сохраняет значение в файле настроек или обновляет графический интерфейс.

public class SettingsActivity extends PreferenceActivity {

    private String oldCatName;
    private EditTextPreference catName;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.settings);

        catName = (EditTextPreference) findPreference("cat_name");
        oldCatName = catName.getText();

        catName.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newVal) {
                final String value = (String) newVal;
                if (value.equals("")) {
                    catName.setText(oldCatName);                
                    Log.e("new value", catName.getText());
                }
                else
                    oldCatName = value;
                return true;
            }
        });
    }
}

Спасибо за помощь! -Майкл

Изменить: уточнение. Логика в операторе if выполняется правильно. Строковое значение EditTextPreference даже корректно обновляется. Тем не менее, значение в графическом интерфейсе, если пользователь нажимает на EditTextPreference снова не обновляется правильно, а значение в общих настройках приложения не обновляется правильно. Это остается пустым.

2 ответа

Решение

Наконец, нашли решение, выполнив следующее:

  • Я использовал SharedPreferences.OnSharedPreferenceChangeListener вместо Preference.OnPreferenceChangeListener, Preference.OnPreferenceChangeListener ищет, когда пользователь изменяет предпочтение через меню настроек, и ведет себя до того, как изменение будет зафиксировано в данных предпочтения. SharedPreferences.OnSharedPreferenceChangeListener прислушивается к изменениям фактических данных о предпочтениях, а не изменений в графическом интерфейсе, поэтому это происходит немного позже. Я заметил, что в моей первой попытке я мог бежать setText() сразу же после getText() на моем EditTextPreference объект, а getText() значение не будет соответствовать тому, что я только что установил setText() значение до. Я не уверен, почему это происходит, но я жду, пока изменения действительно будут внесены, прежде чем пытаться запустить setText() привело к правильному ответу. Может быть, это была проблема времени?

  • я бегу setPreferenceScreen(null) а также addPreferencesFromResource(R.xml.settings) после обновления значения в EditTextPreference, Если бы я этого не делал, иногда, когда пользователь нажимал на EditTextPreference Опять же, значение в поле будет выглядеть пустым, даже если значение в файле настроек не было. Это заставляет страницу настроек более или менее обновляться.

Рабочий код ниже:

public class SettingsActivity extends PreferenceActivity {

    private String oldCatName;
    private EditTextPreference catName;
    private SharedPreferences.OnSharedPreferenceChangeListener listener;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
        createListener();
        catName = (EditTextPreference) findPreference("cat_name");
        oldCatName = catName.getText();
    }

    private void createListener() {
        listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
            @Override
            public void onSharedPreferenceChanged(
                    SharedPreferences sharedPreferences, String key) {
                String value = sharedPreferences.getString("cat_name", "NULL");
                if (value.equals("")) {
                    catName.setText(oldCatName);
                    setPreferenceScreen(null);
                    addPreferencesFromResource(R.xml.settings);
                } else {
                    oldCatName = value;
                }
            }
        };
        PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
            .registerOnSharedPreferenceChangeListener(listener);
    }
}

~9 лет с опозданием, надеюсь, это поможет кому-то еще.
Я тоже столкнулся с подобной проблемой. Это можно сделать, просто вернув false. Как указано в документации , возврат true обновит значение, и вы хотите игнорировать изменения.

      catName.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newVal) {
            final String value = (String) newVal;
            if (value.equals("")) {
                catName.setText(oldCatName);                
                Log.e("new value", catName.getText());
                return false ; // <----------------------------------
            }
            else
                oldCatName = value;
            return true;
        }
    });
Другие вопросы по тегам