Обработка фрагмента фрагмента при повороте экрана (с примером кода)
Есть несколько похожих ответов, но не в этой ситуации.
Моя ситуация проста.
У меня есть Деятельность с двумя разными макетами, один в Портрет, другой в Пейзаж.
ВПортрет, я использую<FrameLayout>
и добавитьFragment
внутрьдинамично.
ВПейзаж, я использую<fragment>
так чтоFragment
являетсястатический. (на самом деле это не имеет значения)
Сначала начинается вПортретЗатем я добавилFragment
просто:
ListFrag listFrag = new ListFrag();
getSupportFragmentManager().beginTransaction()
.replace(R.id.FragmentContainer, listFrag).commit();
гдеListFrag extends ListFragment
.
Затем я делаю поворот экрана.Я обнаружил, что listFrag воссоздается в ландшафтном режиме. (В котором я заметилonCreate()
метод вызывается снова с ненулевым Bundle)
я пытался использоватьsetRetainInstance(false)
как сказал @NPike вэта почта, НоgetRetainInstance()
ужеfalse
по умолчанию. Это не делает то, что я ожидал, какдокументы сказал. Может ли кто-нибудь объяснить, пожалуйста?
Фрагмент, с которым я имею дело, являетсяListFragment
что делаетsetListAdapter()
вonCreate()
, Так чтоif (container == null) return null;
метод не может быть использован здесь. (или я не знаю, как подать заявку).
Я получил некоторые подсказки отэта почта, Должен ли я использоватьif (bundle != null) setListAdapter(null); else setListAdapter(new ...);
в моемListFragment
? Но есть ли более хороший способ действительно удалить / удалить фрагмент, когда он уничтожен / отделен, вместо того, чтобы делать это во время его создания? (так какif (container == null) return null;
метод)
Редактировать:
Единственный аккуратный способ, который я нашел, это делатьgetSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentById(R.id.FragmentContainer)).commit();
вonSaveInstanceState()
, Но это поднимет другие проблемы.
Когда экран частично затенен, как всплывают диалоговые окна WhatsApp или TXT, фрагмент также исчезнет.(это относительно незначительно, только визуальная проблема)
Когда экран поворачивается, действие полностью уничтожается и воссоздается. Так что я могу повторно добавить фрагмент вonCreate(Bundle)
или жеonRestoreInstanceState(Bundle)
, Но в случае (1), а также переключения деятельности, ниonCreate(Bundle)
ниonRestoreInstanceState(Bundle)
будет вызван, когда пользователь вернется к моей активности. Мне некуда воссоздать Activity (и получить данные из Bundle).
Извините, я не сказал это ясно, у меня уже есть решение, котороеgetSupportFragmentManager()...replace(...).commit();
линия работает только в портретном режиме.
Я извлек простой код, для лучшей иллюстрации ситуации :)
MainActivity.java
package com.example.fragremovetrial;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.FragmentContainer) != null) {
System.out.println("-- Portrait --"); // Portrait
ListFrag listFrag = new ListFrag();
getSupportFragmentManager().beginTransaction()
.replace(R.id.FragmentContainer, listFrag).commit();
} else {
System.out.println("-- Landscape --"); // Landscape
}
}
@Override
protected void onResume() {
super.onResume();
if (findViewById(R.id.FragmentContainer) != null) {
System.out.println("getRetainInstance = " +
getSupportFragmentManager().findFragmentById(R.id.FragmentContainer).getRetainInstance());
}
}
}
макет / activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/FragmentContainer"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
Макет-земля / activity_main.xml (не имеет значения)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout>
ListFrag.java
package com.example.fragremovetrial;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.widget.ArrayAdapter;
public class ListFrag extends ListFragment {
private String[] MenuItems = { "Content A", "Contnet B" };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println("ListFrag.onCreate(): " + (savedInstanceState == null ? null : savedInstanceState));
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, MenuItems));
}
}
Обратите внимание, я получил следующее
Отладочные сообщения- портрет -
ListFrag.onCreate (): null
getRetainInstance = false
(повернуть Порт -> Земля)
ListFrag.onCreate (): Bundle [{android: view_state=android.util.SparseArray@4052dd28}]
- Пейзаж -
Ранее сфокусированное представление сообщило идентификатор 16908298 во время сохранения, но не может быть найдено во время восстановления.
(поверните Землю -> Порт)
ListFrag.onCreate (): Bundle [{android: view_state=android.util.SparseArray@405166c8}]
- портрет -
ListFrag.onCreate (): null
getRetainInstance = false
(повернуть Порт -> Земля)
ListFrag.onCreate (): Bundle [{android: view_state=android.util.SparseArray@4050fb40}]
- Пейзаж -
Ранее сфокусированное представление сообщило идентификатор 16908298 во время сохранения, но не может быть найдено во время восстановления.
(поверните Землю -> Порт)
ListFrag.onCreate (): Bundle [{android: view_state=android.util.SparseArray@40528c60}]
- портрет -
ListFrag.onCreate (): null
getRetainInstance = false
где будет создан номер фрагментане увеличивайте бесконечно, пока экран продолжает вращаться, что я не могу объяснить. (пожалуйста помоги)