2013-12-05 5 views
5

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

  1. Я не устанавливаю setRetainInstance.
  2. фрагмент не добавляются в деятельности OnCreate (добавлено позже, когда кнопка касания)
  3. Я могу видеть OnDestroy вызывается для деятельности при вращении
  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(); 

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

+0

Хорошо, когда вы вращаете свое устройство, отображается ли этот фрагмент? Тот, который был добавлен нажатием кнопки? –

+0

@ M-WaJeEh Да, вновь созданный фрагмент показан – RunLoop

ответ

14

Когда мероприятие перезапускается из-за изменения ориентации, 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, вы, вероятно, его не увидите. Попробуйте заменить Fragments:

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

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

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

+0

@Hermann Я не добавляю фрагмент в onCreate. Он добавляется, когда пользователь нажимает кнопку. – RunLoop

+0

Нажимали кнопку несколько раз перед поворотом? – thaussma

+0

@Hermann Кнопка нажимается только один раз. – RunLoop

0

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

Я не добавляю фрагмент в onCreate. Он добавляется, когда пользователь нажимает кнопку. – RunLoop

+0

Да, я вижу, вы отредактировали свой вопрос. –

2

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

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

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

Ваш фрагмент, вероятно, сохраняется в объекте 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); 
    } 
+0

, что присвоение 'null' просто укажет копию этого дескриптора на null. вы должны означать 'savedInstanceState.clear()'. – hsl

1

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

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

Для

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

Наслаждайтесь

Смежные вопросы