Intereting Posts
FragmentTabHost – нет закладки, известной для тега null Получение информации о продуктах, таких как имя, цена и т. Д. С использованием номера штрих-кода Ошибка синхронизации Gradle в студии Android при импорте проекта Элементы меню не отображаются на панели действий. Настройте android EditText, чтобы разрешить десятичные и отрицательные значения SetHintTextColor () в EditText Как загрузить несколько андроидных архивов (по одному на каждый вкус) В Android / Gradle, как определить задачу, которая запускается только при создании конкретного buildType / buildVariant / productFlavor (v0.10 +) Как декомпилировать файл APK или DEX на платформе Android? Значок не отображается в уведомлении: вместо этого показан белый квадрат Android Studio, не включая SDK AsyncTask Android – шаблон дизайна и возвращаемые значения Есть ли способ отключить затухание, что viewPager имеет прокрутку к краям? Установите начальный фокус в приложении для Android Android-клавиатура с Emoji

Почему 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 .