DialogPreference не сохраняет предпочтения, когда я этого ожидаю? - PullRequest
0 голосов
/ 27 сентября 2018

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

1) откройте приложение, и основное действие покажетзначение foo из общих настроек по умолчанию = 1

2) перейти к настройкам

3) нажать на настройку foo, которая открывает мою DialogPreference и показывает значение = 1

4) введитезначение 3

5) закрыть мои DialogPreference с помощью кнопки Ok

***** общие настройки по умолчанию foo теперь должны быть 3

6) нажмите на настройку foo, которая открывает мойDialogPreference и показывает значение = 1

*****, поэтому моя DialogPreference не сохранила настройку общих настроек по умолчанию?

7) отменить диалог

8) перейтивернуться к основному действию, которое показывает значение foo из общих настроек по умолчанию = 3

*****, поэтому моя DialogPreference сохранила настройку общих настроек по умолчанию

9) перейти к настройкам

10) нажмите на настройку foo, которая откроет мою DialogPreference и покажет значение 3

Почему на шаге (6) не указано значение общих предпочтений по умолчанию foo = 3?

Itкажется, что предпочтение сохраняется в общих предпочтениях по умолчанию, только когда поток возвращается к основному действию из списка настроек, что противоречит интуитивно понятному сохранению предпочтения в методе onDialogClosed для DialogPreference.

MyDialogPreference

public class MyDialogPreference extends DialogPreference
{
private static final String DEFAULT_VALUE = "0";
private String value = DEFAULT_VALUE;
private EditText editText;

public MyDialogPreference(Context context, AttributeSet attrs)
{
    super(context, attrs);
    setDialogLayoutResource(R.layout.constrained_integer_preference);
}

@Override
public void onBindDialogView(View view)
{
    super.onBindDialogView(view);

    editText = (EditText) view.findViewById(R.id.edit);
    editText.setText("" + value);
}

@Override
protected void onDialogClosed(boolean positiveResult)
{

    if (positiveResult)
    {
        persistString(editText.getText().toString());
    }

    super.onDialogClosed(positiveResult);
}

@Override
protected Object onGetDefaultValue(TypedArray typedArray, int index)
{
    return typedArray.getString(index);
}

@Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue)
{

    if (restorePersistedValue)
    {
        value = getPersistedString(DEFAULT_VALUE);
    }
    else
    {
        value = (String) defaultValue;

        if (shouldPersist())
        {
            persistString(value);
        }

    }

}

}

РЕДАКТИРОВАТЬ: Таким образом, похоже, что предпочтение, которое я обрабатываю с моим DialogPreference, не имеет ключа, который вызывает все проблемы.Но я указал ключ в файле Preferences.xml для этого DialogPreference.Я перепробовал все, чтобы заставить ключ быть распознанным, но ничего не работает.

Может кто-нибудь сказать мне, как я получаю DialogPreference для получения ключа android: из файла preferences.xml для работы?

preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<org.mycompany.myproject.MyDialogPreference
    android:defaultValue="11"
    android:dialogLayout="@layout/my_preference"
    android:inputType="number"
    android:key="MY_KEY"
    android:selectAllOnFocus="true"
    android:singleLine="true"
    android:summary="summary"
    android:title="My Preference" />
</PreferenceScreen>

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

В какой-то момент я всегда чувствую, что взламываю Android, и это определенно взлом.

Сначала я думал, что проблема, с которой я борюсь, заключается в том, что фреймворк игнорирует мой android: ключ,потому что getKey () возвращает пустую строку, но это не может быть правдой, потому что он получает постоянное значение при запуске PreferenceScreen и сохраняет мои измененные значения в общих настройках при закрытии DialogPreference.

Так что этоКажется, проблема, с которой я борюсь, состоит в том, что платформа считывает постоянные значения предпочтений для внутренних членов, а затем использует внутренние члены, пока поток не выйдет из структуры предпочтений, не обновляя их после закрытия DialogPreference.

Но я наконец-то нашел способ заставить PreferenceScreen обновлять постоянные значения настроек, которые он хранит во внутренних элементах.Хотя на самом деле это не обновление, это взлом.

Так что я просто выбрасываю PreferenceScreen и создаю новый.Я делаю это, добавляя следующий код в мой метод SettingsFragment.onCreate непосредственно перед addPreferencesFromResource (R.xml.preferences).

    SharedPreferences.OnSharedPreferenceChangeListener prefListener = (prefs, key) ->
    {
        setPreferenceScreen(null);
        addPreferencesFromResource(R.xml.preferences);
    };

    PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()).registerOnSharedPreferenceChangeListener(prefListener);

Это, вероятно, плохо.Я проверял его, несколько раз, хотя и не тщательно, и до сих пор не наблюдал каких-либо побочных эффектов.

Так что с этим хаком я теперь могу многократно открывать DialogPreference из PreferenceScreen, сохранять новое значение, затем идтивернитесь к DialogPreference с ранее обновленным значением.

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

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

Еще лучше, если кто-то еще сможет предложить предпочтительное решение, указав, что я сделал неправильно, вызвав проблему,пожалуйста, сделай.

РЕДАКТИРОВАТЬ: После столь долгой работы этот хак в итоге сломался, и последовательно.

Но, удаляя хак, я подошел к проблеме со свежимпомните, и, используя тот факт, что я определил, что диалоговое окно получает ключ предпочтения, я использовал это исправление для проблемы, которая работает отлично.

Я добавил эту строку кода в начало onBindDialogView

value = getSharedPreferences().getString(getKey(), "-1");

Что делает вызовы onGetDefaultValue и onSetInitialValue избыточными, но они просто не работают должным образом, по крайней мере, не для меня.

EDIT: omg, я ненавижуthis!

Я не заметил, что во время более раннего рефакторинга была удалена строка кода, которая обновляет внутреннее значение DialogPreference в onDialogClosed.

Обычно это что-то простое, и со всем остальным я проверялЯ пропустил это небольшое изменение.

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

0 голосов
/ 27 сентября 2018

вам придется реализовать OnPreferenceChangeListener и / или вызвать notifyChanged () .

, если вы не предоставите код этого DialogPreference, этоТрудно воспроизвести проблему.

...