Лучший способ переключения между двумя фрагментами

меня интересует лучший способ иметь одну активность, которая переключается между двумя фрагментами.

Я прочитал, вероятно, 15 сообщений о переполнении стека и 5 сообщений в блогах о том, как это сделать, и, хотя я думаю, что я собрал решение, я не уверен, что это лучший. Итак, я хочу услышать мнения людей о том, как правильно справиться с этим, особенно в отношении жизненного цикла родительской деятельности и фрагментов.

вот ситуация в деталь:

  1. родительское действие, которое может отображать один из двух возможных фрагментов.
  2. два фрагмента имеют состояние, что я хотел бы сохраняться в течение сеанса, но не обязательно должен сохраняться между сеансами.
  3. ряд других действий, таких как родительская деятельность и фрагменты могут быть похоронены в заднем стеке и уничтожены из-за низкой памяти.
  4. Я хочу иметь возможность использовать кнопку "Назад" для перехода между фрагменты (насколько я понимаю, я не могу использовать setRetainInstance).

в дополнение к общим советам по архитектуре у меня есть следующие нерешенные вопросы:

  1. если родительская активность уничтожена из-за низкой памяти, как я могу гарантировать, что состояния обоих фрагментов будут сохранены, согласно этому сообщению: когда фрагмент заменяется и помещается в задний стек (или удаляется), он остается в памяти?. Мне просто нужен указатель на каждый фрагмент в родительской деятельности?
  2. каков наилучший способ для родительской активности отслеживать, какой фрагмент он в настоящее время отображает?

спасибо заранее!

2 ответов


Я закончил добавление обоих фрагментов с помощью диспетчера фрагментов поддержки, а затем с помощью detach/attach для переключения между ними. Я смог использовать commitAllowingStateLoss (), потому что я сохраняю состояние представления в другом месте и вручную устанавливаю правильный фрагмент в onResume ().

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    

    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.my_layout, new AFragment(), TAG_A);
    fragmentTransaction.add(R.id.my_layout, new BFragment(), TAG_B);
    fragmentTransaction.commit();
}

public void onResume() {
    super.onResume();
    if (this.shouldShowA) {
        switchToA();
    } else {
        switchToB();
    }
}

private void switchToA() {
    AFragment fragA = (AFragment) getSupportFragmentManager().findFragmentByTag(TAG_A);
    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    fragmentTransaction.detach(getSupportFragmentManager().findFragmentByTag(TAG_B));
    fragmentTransaction.attach(fragA);
    fragmentTransaction.addToBackStack(null);

    fragmentTransaction.commitAllowingStateLoss();
    getSupportFragmentManager().executePendingTransactions();
}

вы можете рассмотреть возможность использования ViewPager в вашей родительской активности, так что вы можете переключаться между фрагментами.

таким образом, Вы сможете провести через них.

если вы хотите сохранить их состояние во время сеанса, даже если родительская активность уничтожена, вам нужно сделать их Parcelable, поэтому вы можете сохранить состояние, даже если класс не создан в это время. Вам также нужно сделать это, если вы вращаете свое устройство и хотите сохранить текущую ситуацию/данные на экране.

вы должны написать их в Parcelable в своем onPause методы и воссоздать их в onResume один. Таким образом, не имеет значения, будут ли они уничтожены или должны быть воссозданы из-за изменения ориентации устройств.

если вы хотите иметь возможность переключаться между этими фрагментами с помощью кнопки Backbutton, вы можете поймать buttonClick для onBackPressed и обращаться с ним соответственно.

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