Обработка фрагмента фрагмента при повороте экрана (с примером кода)

Есть несколько похожих ответов, но не в этой ситуации.

Моя ситуация проста.

У меня есть Деятельность с двумя разными макетами, один в Портрет, другой в Пейзаж.

ВПортрет, я использую и добавить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


Макет-земля / activity_main.xml (Безразлично»не имеет значения)



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

где будет создан номер фрагментане бесконечно увеличиваться по мере того, как экран продолжает вращаться, что я не могу объяснить. (пожалуйста помоги)

Ответы на вопрос(4)

Ваш ответ на вопрос