Intereting Posts
Eclipse IDE – графическая компоновка Android и макет XML рядом друг с другом Плагин Eclipse ADT – инструмент для графического компоновки памяти и хранения памяти Могу ли я создать плагин для whatsapp Фрагменты, перекрывающиеся с DrawerLayout / NavigationView Преобразование результатов Sqllite Cursor в мой объект Как использовать DrawerLayout для отображения на панели ActionBar / Toolbar и в строке состояния? API Карт Google v2: LatLngBounds от CameraPosition Как объединить несколько операций greenDAO Tx в одну транзакцию? Нет ActionBar в PreferenceActivity после обновления до поддержки библиотеки v21 Как добавить эффект скручивания в представлении пейджер Поддержка WebSocket на мобильных устройствах Android: Как растянуть изображение до ширины экрана при сохранении пропорций? Как перезапустить службу после того, как приложение было убито из недавних задач API-интерфейс на стороне сервера для мобильных приложений Использование FragmentManager для доступа к методам фрагментов из активности

Почему Fragment не сохраняет состояние при вращении экрана?

У меня возникли проблемы с получением некоторых пользовательских подклассов DialogPreference внутри PreferenceFragment, чтобы оставаться видимыми при повороте экрана. Я не испытываю этой проблемы при использовании PreferenceActivity, поэтому я не знаю, является ли это ошибкой Android или проблемой с моим кодом, но я бы хотел, чтобы кто-то подтвердил, имеют ли они такой же опыт.

Чтобы проверить это, сначала создайте экран предпочтений, содержащий хотя бы один диалог DialogPreference (неважно, какой подкласс). Затем отобразите его в PreferenceActivity. Когда вы запустите приложение, нажмите на DialogPreference, чтобы он показывал диалог. Затем поверните экран так, чтобы ориентация изменилась. Диалог остается видимым?

Затем попробуйте сделать то же самое, но с PreferenceFragment, чтобы отображать ваши предпочтения вместо PreferenceActivity. Опять же, диалог остается видимым при повороте экрана?

До сих пор я обнаружил, что диалог останется видимым при использовании PreferenceActivity, но не при использовании PreferenceFragment. Рассматривая исходный код для DialogPreference , кажется, что правильное поведение заключается в том, что диалог останется видимым, поскольку isDialogShowing – это информация о состоянии, которая сохраняется, когда onSaveInstanceState() вызывается при переориентации экрана. Поэтому я считаю, что ошибка может препятствовать восстановлению этой информации о состоянии PreferenceFragment (и всего внутри него).

Если это ошибка Android, это имеет далеко идущие последствия, поскольку любой, кто использует PreferenceFragment, не может сохранять и восстанавливать информацию о состоянии.

Может кто-нибудь, пожалуйста, подтвердите? Если это не ошибка, то что происходит?

Solutions Collecting From Web of "Почему Fragment не сохраняет состояние при вращении экрана?"

Наконец выяснилось решение этой проблемы. Оказывается, это не ошибка, а проблема / надзор в документации разработчика Android.

Понимаете, я следил за учебником PreferenceFragment. В этой статье вам предлагается сделать следующее, чтобы создать экземпляр вашего PreferenceFragment в рамках Activity:

 public class SettingsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Display the fragment as the main content. getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingsFragment()) .commit(); } } 

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

Первое создание произойдет через вызов Activity для super.onCreate() (показано выше), который вызовет метод onActivityCreated() для вашего метода PreferenceFragment () и onRestoreInstanceState() для каждого Предпочтения, которое он содержит. Они будут успешно восстанавливать состояние всего.

Но затем, как только этот вызов super.onCreate() вернется, вы увидите, что onCreate() метод onCreate() продолжит создание PreferenceFragment во второй раз. Поскольку это бессмысленно создано снова (и на этот раз, без информации о состоянии!), Все состояние, которое было просто успешно восстановлено, будет полностью отброшено / потеряно. Это объясняет, почему DialogPreference, который может отображаться в момент уничтожения Activity, больше не будет отображаться после восстановления Задания.

Так в чем же решение? Ну, просто добавьте небольшую проверку, чтобы определить, был ли PreferenceFragment уже создан, например:

 public class SettingsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fragment existingFragment = getFragmentManager().findFragmentById(android.R.id.content); if (existingFragment == null || !existingFragment.getClass().equals(SettingsFragment.class)) { // Display the fragment as the main content. getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingsFragment()) .commit(); } } } 

Или другой способ – просто проверить, предназначено ли для функции onCreate() для восстановления состояния или нет:

 public class SettingsActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { // Display the fragment as the main content. getFragmentManager().beginTransaction() .replace(android.R.id.content, new SettingsFragment()) .commit(); } } } 

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

Ответ здесь привел меня к пониманию этого решения.

У меня действительно была эта проблема. Существует ошибка, при которой DialogFragment не восстанавливает состояние, потому что оно равно null или, по крайней мере, со мной.

Используя несколько источников, я в конечном итоге получил решение. Диалоговое расширение BaseDialogFragment :

 import android.app.Dialog; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.support.v4.app.DialogFragment; import com.actionbarsherlock.app.SherlockDialogFragment; public class BaseDialogFragment extends DialogFragment { @Override public void onCreate(Bundle savedInstanceState) { if (savedInstanceState == null || savedInstanceState.isEmpty()) savedInstanceState = WorkaroundSavedState.savedInstanceState; setRetainInstance(true); Log.d("TAG", "saved instance state oncreate: " + WorkaroundSavedState.savedInstanceState); super.onCreate(savedInstanceState); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { if (savedInstanceState == null || savedInstanceState.isEmpty()) savedInstanceState = WorkaroundSavedState.savedInstanceState; Log.d("TAG", "saved instance state oncretaedialog: " + WorkaroundSavedState.savedInstanceState); return super.onCreateDialog(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (savedInstanceState == null || savedInstanceState.isEmpty()) savedInstanceState = WorkaroundSavedState.savedInstanceState; Log.d("TAG", "saved instance state oncretaeview: " + WorkaroundSavedState.savedInstanceState); return super.onCreateView(inflater, container, savedInstanceState); } @Override public void onDestroyView() // necessary for restoring the dialog { if (getDialog() != null && getRetainInstance()) getDialog().setOnDismissListener(null); super.onDestroyView(); } @Override public void onSaveInstanceState(Bundle outState) { // ... super.onSaveInstanceState(outState); WorkaroundSavedState.savedInstanceState = outState; Log.d("TAG", "saved instance state onsaveins: " + WorkaroundSavedState.savedInstanceState); } @Override public void onDestroy() { WorkaroundSavedState.savedInstanceState = null; super.onDestroy(); } /** * Static class that stores the state of the task across orientation * changes. There is a bug in the compatibility library, at least as of the * 4th revision, that causes the save state to be null in the dialog's * onRestoreInstanceState. */ public static final class WorkaroundSavedState { public static Bundle savedInstanceState; } } 

Обратите внимание, что в любых подклассах, у которых есть параметр savedInstanceState , вам может потребоваться вызвать super с помощью WorkaroundSavedState.savedInstanceState . И когда вы восстанавливаете состояние (т. onCreate() , просто игнорируйте savedInstanceState и вместо этого используйте savedInstanceState . Статический держатель не является самым чистым решением, но он работает. Просто убедитесь, что он установлен в null в вашем onDestroy() .

В любом случае мой DialogFragment не исчезает, когда я поворачиваю экран (и это без каких-либо configChanges ). Дайте мне знать, относится ли этот код к вашей проблеме, и если нет, я посмотрю, что происходит. Также обратите внимание, что я не тестировал это внутри PreferenceFragment а вместо этого другие Fragment из класса совместимости или ActionBarSherlock .