Фрагмент не разрушен при вращении
У меня есть фрагмент, который добавляется программно. Однако я обнаружил, что после вращения создается новый фрагмент, но старый фрагмент все еще жив (хотя и не отображается). Я предположил, что фрагменты уничтожаются вместе с активностью при вращении, но здесь это не так. Что может привести к тому, что мой фрагмент будет сохранен/не уничтожен?
Обратите внимание:
- Я не устанавливаю setRetainInstance.
- Фрагмент не добавляется в действие onCreate (добавляется позже при нажатии кнопки)
- Я вижу, что onDestroy вызывается для Activity после ротации.
- Хотя фрагмент добавлен, он закрывает кнопку добавления и увольняется только после выполнения "удаления".
Код, создающий фрагмент:
MyFragment fragment = MyFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.content_frame, fragment, "CurrentFragment");
fragmentTransaction.show(fragment).commit();
Код удаления фрагмента:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragment).commit();
UPDATE:
Я не могу подтвердить, была ли эта проблема, но фрагмент регистрируется как приемник LocalBroadcast в onCreate. Он незарегистрирован для трансляций в onDestroy, но кажется, что либо регистрация LocalBroadcast препятствовала вызову onDestroy, либо onDestroy не вызывался при ротации. Теперь я отменил регистрацию в onStop, и это, похоже, решило проблему.
Ответы
Ответ 1
Когда действие перезапускается из-за изменения ориентации, Android Framework воссоздает и автоматически добавляет фрагмент.
Вероятно, вы добавите фрагмент в onCreate
вашего Activity
. Это, когда вы добавляете дополнительный фрагмент после изменения ориентации.
Вам нужно проверить, добавлен ли фрагмент:
Fragment f = getFragmentManager().findFragmentById(R.id.content_frame);
if(f == null){
//Add it, there is no Fragment
}else{
//It already there
}
При каждом нажатии кнопки, которая добавляет фрагмент, будет добавлен новый фрагмент. Если ваш контейнер является FrameLayout, вы, вероятно, его не увидите. Попробуйте заменить фрагменты:
fragmentTransaction.replace(R.id.content_frame, fragment, "CurrentFragment");
Метод setRetainInstance(true)
имеет другую цель. Если вы включите его, экземпляр Fragment
не будет уничтожен при изменении ориентации (но его виды будут уничтожены). Это означает, что вы можете хранить данные в переменных-членах Fragment
, и эти данные по-прежнему будут доступны после изменения ориентации.
При настройке setRetainInstance(true)
жизненный цикл фрагмента несколько отличается. То есть onCreate()
и onDestroy()
не вызываются (потому что это событие не происходит)
Ответ 2
Почему не можете заменить существующий фрагмент новым фрагментом, который вы хотите загрузить.
попробуйте, это может вам помочь.
FragmentNew mFragmentNew = new FragmentNew ();// Which you want to load That Fragment Object
getFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, mFragmentNew)
.commit();
Ответ 3
Ваш фрагмент, вероятно, сохранит объект Bundle перед активностью onDestroy(). Попробуйте обработать удаление фрагментов в onSaveInstanceState():
@Override
protected void onSaveInstanceState(Bundle outState) {
//remove here fragments
super.onSaveInstanceState(outState);
}
Или вы можете просто сделать Bundle null в onCreate():
@Override
protected void onCreate(Bundle savedInstanceState) {
savedInstanceState = null;
super.onCreate(savedInstanceState);
}
Ответ 4
У меня была эта проблема, и я решил ее просто Заменить эту строку
fragmentTransaction.add(R.id.content_frame, fragment, "CurrentFragment");
Для
fragmentTransaction.replace(R.id.content_frame, fragment, "CurrentFragment");
Enjoy
Ответ 5
Вам просто нужно добавить Fragment
один раз при первом запуске, сделайте это так:
Следующий код скопирован из http://developer.android.com/reference/android/app/Fragment.html, комментарий мой:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// My Comment: only add when launched for the first time, it won't be null on orientation change
if (savedInstanceState == null) {
// During initial setup, plug in the details fragment.
DetailsFragment details = new DetailsFragment();
details.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().add(android.R.id.content, details).commit();
}
}