Фрагменты Android воссозданы при изменении ориентации
Я разрабатываю приложение, в котором в основном есть ActionBar. Когда мое приложение запускается, Activity создает фрагменты и привязывает их к каждой вкладке, поэтому при переключении я получаю разные представления.
Проблемы возникают, когда я пытаюсь повернуть устройство. После некоторой борьбы я заметил, что Android автоматически воссоздает ранее добавленные фрагменты, такие как:
SummaryFragment.onCreate(Bundle) line: 79
FragmentManagerImpl.moveToState(Fragment, int, int, int) line: 795
FragmentManagerImpl.moveToState(int, int, int, boolean) line: 1032
FragmentManagerImpl.moveToState(int, boolean) line: 1014
FragmentManagerImpl.dispatchCreate() line: 1761
DashboardActivity(Activity).onCreate(Bundle) line: 864
...
а затем я воссоздаю фрагменты, как обычно. Поэтому у меня есть "настоящие" фрагменты, которые я ожидаю работать правильно, и их "скрытые" Android-создатели, которые приводят к сбою моего приложения. Как я могу избежать такого поведения? Я уже пытался вызвать setRetainInstance (false) в SummaryFragment.
Спасибо
Ответы
Ответ 1
Вам нужно проверить сохраненный файлInstanceState [edit: в родительской активности], и если он существует, не создавайте свои фрагменты.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (savedInstanceState == null) {
// Do your oncreate stuff because there is no bundle
}
// Do stuff that needs to be done even if there is a saved instance, or do nothing
}
Ответ 2
Если у вас есть аналогичные ui (без конкретных файлов макета) для обеих ориентаций, вы можете установить android:configChanges="keyboardHidden|orientation"
на активность в вашем файле манифеста.
Если вы не указали, пожалуйста, исходный код, в котором вы добавляете фрагменты к вкладкам, и я попытаюсь помочь вам с улучшениями.
Ответ 3
Когда вы создаете свою активность, убедитесь, что она еще не существует. Если он существует, ничего не делать... Android воссоздает его для вас.
private void initFragment() {
FragmentManager fragMgr = getSupportFragmentManager();
if (fragMgr.findFragmentByTag(LEADERBOARD_FRAG_TAG) != null) { return; }
frag = new HdrLeaderboardFragment();
FragmentTransaction ft = fragMgr.beginTransaction();
ft.replace(R.id.leaderboard_fragment_wrapper, frag, LEADERBOARD_FRAG_TAG);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
}
Ответ 4
Я не уверен, есть ли лучшее решение, но это то, что я сделал в последней программе.
Когда фрагмент создается автоматически системой при изменении ориентации, и если вы хотите отслеживать их в активности хоста, поймайте их в методе OnAttachFragment()
активности хоста. И они получают аргументы по умолчанию, поэтому вы можете использовать их, чтобы узнать, какой фрагмент он есть.
public void onAttachFragment(Fragment fragment) {
super.onAttachFragment(fragment);
if (fragment != null) {
if(fragment.getArguments() != null) {
switch (fragment.getArguments().getString(ARG_PARAM1)) {
case FragmentATag:
if (myFragmentA != fragment) {
myFragmentA = (FragmentA) fragment;
}
break;
case FragmentBTag:
if (myFragmentB != fragment) {
myFragmentB = (FragmentB) fragment;
}
break;
}
}
}
}