Что сохранить в Preference.onSaveInstanceState - PullRequest
3 голосов
/ 29 июня 2011

Я создаю несколько пользовательских настроек для приложения Android.

Два, которые я создаю, это SeekBarPreference и MultiSelectPreference.

SeekBarPreference довольно прост, он наследует от DialogPreference и имеет настраиваемое представление содержимого, в котором отображается SeekBar.

MultiSelectPreference немного более продвинутый, при нажатии открывается Dialog, который имеет пользовательский ListView и кнопку. Когда кнопка нажата, открывается другой Dialog, который имеет общий ListView.

Что я должен сохранить в onSaveInstanceState() для этих предпочтений?
Для SeekBarPreference я предположил, что мне нужно сохранить значение, если isPersistant() равно false, а также текущий прогресс ползунка (чтобы я мог восстановить), но после просмотра исходного кода Android не выглядит как EditTextPreference заботится о сохранении текущего текста, только сохраненное значение.

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

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

1 Ответ

2 голосов
/ 30 июня 2011

После большого количества тестирования и просмотра кода мои выводы:

  • Вам не нужно сохранять состояние представлений, если они подключены к корневому представлению, поскольку они сохраняются при сохранении корневого представления, в моем случае это означает, что мне не нужно сохранять состояние SeekBar, это обрабатывает, когда диалог сохраняется суперклассом.
  • Вы должны всегда сохранять свою ценность, если вы не настойчивы
  • Вы должны сохранить все переменные экземпляра, которые изменяются / могут изменяться после создания предпочтения, это означает, что переменные могут быть изменены с помощью установщика или могут меняться со временем.

Даже если Google не следит за последним пунктом, он ошибается, и простой пример показывает, почему: Представьте, что у вас есть PreferenceActivity, которое содержит две вещи; ListPreference с 10 элементами и общим предпочтением, которое при нажатии добавляет элемент в конец ListPreference.

Теперь представьте, что пользователь запускает приложение и нажимает универсальное предпочтение, ListPreference теперь имеет 11 элементов. Теперь пользователь открывает ListPreference.

Если приложение закрыто и затем уничтожено, экземпляр сохраняется, но ListView сохраняет только сохраненное значение (если оно не является постоянным), поэтому при повторном открытии оно содержит только начальный элемент 10.

Ниже приведен пример минимального приложения, отображающего проблему, просто нажмите кнопку, откройте список (должно быть 4 элемента), закройте приложение с открытым списком, убейте приложение из adb и снова откройте его, список теперь содержит три элемента.

PreferenceTest.java

package com.example;

import java.util.ArrayList;
import java.util.Arrays;

import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;

public class PreferenceTest extends PreferenceActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);

        getPreferenceScreen().findPreference("button").setOnPreferenceClickListener(new OnPreferenceClickListener() {

            @Override
            public boolean onPreferenceClick(Preference preference) {
                ListPreference lp = (ListPreference) getPreferenceScreen().findPreference("list");

                ArrayList<CharSequence> al = new ArrayList<CharSequence>(Arrays.asList(lp.getEntries()));
                CharSequence items[] = new CharSequence[al.size()+1];
                al.add("Item " + items.length);
                lp.setEntries(al.toArray(items));

                al = new ArrayList<CharSequence>(Arrays.asList(lp.getEntryValues()));
                al.add("Value " + items.length);
                lp.setEntryValues(al.toArray(items));

                return true;
            }
        });
    }
}

Рез / XML / preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android">

  <ListPreference
    android:key="list"
    android:entries="@array/list_entries"
    android:entryValues="@array/list_values"
    android:title="Example list"
    android:summary="This list contains 3 items by default" />      

  <Preference
    android:key="button"
    android:title="Example button"
    android:summary="When clicked this adds an item to the list" />

</PreferenceScreen>

Рез / значения / list_items.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="list_entries">
        <item>Item 1</item>
        <item>Item 2</item>
        <item>Item 3</item>
    </string-array>

    <string-array name="list_values">
        <item>Value 1</item>
        <item>Value 2</item>
        <item>Value 3</item>
    </string-array>
</resources>    
...