Фрагменты Отсоединить/Повторно прикрепить против Показать/Скрыть

У меня возникают проблемы с определением правильного способа навигации по фрагментам без пейджера, и у меня возникают проблемы при изменении конфигурации для ориентации экрана. Я использую Show/Hide для фрагментов, чтобы сделать их видимыми и функциональными, но мне интересно, следует ли вместо этого использовать Detach/Attach. У меня также возникают проблемы с добавлением вещей в задний стек, и я думаю, что это также связано с использованием show/hide. Лучше ли использовать «Присоединить/отсоединить» или есть способ переопределить действие кнопки «Назад», чтобы показать/скрыть последний/текущий фрагмент.

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

Здесь я создаю фрагменты и добавляю их в диспетчер фрагментов. Я также показал, где я показываю/скрываю фрагменты.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_map_frags);
    mapViewContainer = LayoutInflater.from(this)
            .inflate(R.layout.map, null);

    setupFragments();
    showFragment(0);
}
public void setListData(String name) {
    bName = name;
    showFragment(1);
}
private void setupFragments() {
    final FragmentManager fm = getSupportFragmentManager();
    final FragmentTransaction ft = fm.beginTransaction();
    mFragment1 = fm.findFragmentByTag("f1");
    if (mFragment1 == null) {
        mFragment1 = new MenuFragment();
        ft.add(mFragment1, "f1");
        ft.hide(mFragment1);
    }
    mMapFragment = (MapFragment) getSupportFragmentManager()
            .findFragmentByTag(MapFragment.TAG);
    if (mMapFragment == null) {
        mMapFragment = MapFragment.newInstance(0);
        ft.add(R.id.fragment_container, mMapFragment, MapFragment.TAG);
    }
    ft.hide(mMapFragment);

    myListFragment = (ListFrag) getSupportFragmentManager()
            .findFragmentByTag(ListFrag.TAG);
    if (myListFragment == null) {
        myListFragment = new ListFrag();
        ft.add(R.id.fragment_container, myListFragment, ListFrag.TAG);
    }
    ft.hide(myListFragment);

    frag = (frag) getSupportFragmentManager().findFragmentByTag(
            frag.TAG);
    if (frag == null) {
        bacFrag = new frag();
        ft.add(R.id.fragment_container, frag, frag.TAG);
    }
    ft.hide(bacFrag);
    ft.commit();
}

public void showFragment(int fragIn) {
    final FragmentTransaction ft = getSupportFragmentManager()
            .beginTransaction();
    ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
    if (mVisible != null) {
        if (mVisible == mListFragment) {
            ft.remove(mListFragment);
        } else {
            ft.hide(mVisible);
        } 
    }

    switch (fragIn) {
    case 0:
        ft.show(mMapFragment);
        ft.commit();
        mVisible = mMapFragment;
        break;
    case 1:
        mListFragment = (ListFragmentDisplay) getSupportFragmentManager()
                .findFragmentByTag(ListFragmentDisplay.TAG);
        Toast.makeText(this, "startListFrag", Toast.LENGTH_LONG).show();
        if (mListFragment == null) {
            mListFragment = new ListFragmentDisplay();
            ft.add(R.id.fragment_container, mListFragment,
                    ListFragmentDisplay.TAG);
        }
        ft.show(mListFragment).commit();
        mVisible = mListFragment;
        break;
    case 2:
        ft.show(myfragment).commit();
        mVisible = myfragment;
        break;
    case 3:
        ft.show(frag).commit();
        mVisible = frag;
        break;
    }
}

person doubleA    schedule 08.12.2012    source источник
comment
если вы хотите, чтобы ваша активность не перезапускалась при изменении ориентации, вы можете добавить android:configChanges=orientation|keyboardHidden в манифест.   -  person Faizan    schedule 08.12.2012
comment
Detach/Attach освободит ресурсы, а hide/show — нет.   -  person Faizan    schedule 08.12.2012


Ответы (2)


Это не твоя вина. Проблема в том, что при изменении ориентации все действия уничтожаются, даже все добавленные фрагменты. Таким образом, никакие данные внутри него не сохраняются. Не рекомендуется использовать android:configChanges="orientation|keyboardHidden". Вместо этого установите для каждого фрагмента setRetainInstance(true), и он будет хорошо работать с вашим текущим кодом.

person lorenzop    schedule 15.02.2013
comment
Это не работает для нескольких фрагментов на одном экране. Но это решило бы мою проблему выше, если бы я не сдался и не переделал все по-другому. - person doubleA; 01.07.2013
comment
На самом деле это не ответ на вопрос в заголовке. - person stdout; 24.10.2016

Если вы хотите иметь лучшее постоянство (например, когда активность временно уничтожается из-за проблем с местом), также не забудьте сохранить состояние ваших фрагментов с помощью onSaveInstanceState. setRetainInstance будет работать только тогда, когда произойдет изменение конфигурации.

person Bertuz    schedule 18.06.2013