Фрагмент, не разрушенный при вращении

У меня есть фрагмент, который добавлен программно. Однако я обнаружил, что после поворота создается новый фрагмент, но старый фрагмент все еще жив (хотя и не отображается). Я предположил, что фрагменты уничтожаются вместе с действием при вращении, но здесь это не так. Что может быть причиной сохранения / не уничтожения моего фрагмента? Пожалуйста, обратите внимание:

  1. Я не устанавливаю setRetainInstance.
  2. Фрагмент не добавляется в упражнение onCreate (добавляется позже при нажатии кнопки)
  3. Я вижу, что onDestroy вызывается для Activity при ротации.
  4. Несмотря на то, что фрагмент добавлен, он скрывает кнопку добавления и может быть отклонен, только когда я сделаю "удалить".

Код создания фрагмента:

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();

ОБНОВЛЕНИЕ: я не могу подтвердить, была ли это проблема, но фрагмент регистрируется как получатель LocalBroadcast в onCreate. Он не зарегистрирован для трансляций в onDestroy, но кажется, что регистрация LocalBroadcast препятствовала вызову onDestroy или onDestroy не вызывался при ротации. Теперь я отменил регистрацию в onStop, и это, похоже, решило проблему.

5 ответов

Когда действие перезапускается из-за изменения ориентации, Android Framework заново создает и добавляет фрагмент автоматически для вас. Вы, вероятно, добавляете фрагмент в onCreate вашей Activity, Вот где вы добавляете дополнительный фрагмент после изменения ориентации.

Вы должны проверить, если фрагмент уже добавлен:

Fragment f = getFragmentManager().findFragmentById(R.id.content_frame);
if(f == null){
    //Add it, there is no Fragment
}else{
    //It's already there
}

Каждый раз, когда вы нажимаете кнопку, которая добавляет фрагмент, будет добавлен новый фрагмент. Если ваш контейнер - FrameLayout, вы, вероятно, его не увидите. Попробуйте заменить фрагменты:

fragmentTransaction.replace(R.id.content_frame, fragment, "CurrentFragment");

Метод setRetainInstance(true) имеет другую цель. Если вы включите его, Fragment Экземпляр не будет уничтожен при изменении ориентации (но его Виды будут уничтожены). Это означает, что вы можете хранить данные в переменных-членах Fragment и эти данные все еще будут доступны после изменения ориентации.

При настройке setRetainInstance(true) Жизненный цикл Фрагмента немного отличается. Т.е. onCreate() а также onDestroy() не называются (потому что тех событий не бывает)

Ваш фрагмент, вероятно, сохраните в объекте Bundle перед действием onDestroy(). Попробуйте обработать удаление фрагментов в onSaveInstanceState():

@Override
    protected void onSaveInstanceState(Bundle outState) {
        //remove here fragments
        super.onSaveInstanceState(outState);
    }

Или вы можете просто сделать Bundle нулевым в onCreate():

@Override
    protected void onCreate(Bundle savedInstanceState) {
        savedInstanceState = null;
        super.onCreate(savedInstanceState);
    }

Почему вы не можете заменить существующий фрагмент новым фрагментом, который вы хотите загрузить.

попробуйте это может помочь вам.

FragmentNew mFragmentNew = new FragmentNew ();// Which you want to load That Fragment Object 
        getFragmentManager().beginTransaction()
                .replace(R.id.item_detail_container, mFragmentNew)
                .commit();

У меня была эта проблема, и я решил ее просто заменить эту строку

fragmentTransaction.add(R.id.content_frame, fragment, "CurrentFragment");

к

fragmentTransaction.replace(R.id.content_frame, fragment, "CurrentFragment");

наслаждаться

Вам просто нужно добавить 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();
    }
}
Другие вопросы по тегам