Пропустить некоторые фрагменты на BackPress
Я довольно новичок с фрагментами Android, поэтому, пожалуйста, потерпите меня.
У меня есть несколько фрагментов, использующих одно действие в качестве хоста.
На мой взгляд, мои фрагменты сгруппированы по разделам, хотя они все еще являются модульными / повторно используемыми по коду. Рассмотрим этот желаемый сценарий:
Frag1 -> (Нажмите Далее) -> Frag2 -> (Нажмите Далее) -> Frag3 -> (Нажмите Назад) -> Frag1
Пройдя серию фрагментов, я хотел бы пропустить некоторые предыдущие фрагменты (в этом случае пропустите Frag 2) при нажатии кнопки "Назад".
Однако в моем текущем коде моя проблема заключается в том, что, несмотря на то, что он возвращается к Frag1, Frag3 не исчезает с экрана. Что происходит, так это то, что и Frag1, и Frag3 становятся видимыми друг над другом.
Вот мои соответствующие фрагменты кода:
Фрагмент кода для создания Frag1
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
// init the fragment (with a default fragment, not null)
Fragment fragment = PlaceholderFragment.newInstance(position + 1);
// Position number from navigation sidebar starts from 0.
// Since position starts from 0, add 1 to match section number
// as implemented in {@link #onSectionAttached()}
switch(position) {
case 0:
fragment = PlaceholderFragment.newInstance(position + 1);
break;
case 1: // Frag1 case
fragment = new AddPointsFragment().newInstance(position + 1, "");
break;
default:
break;
}
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
// clear all fragments from previous section from the back stack
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
// replace all currently added fragments in container and replace with the new fragment
fragmentManager.beginTransaction()
.replace(R.id.container, fragment)
.commit();
}
Фрагмент кода для создания Frag2
public void onEnterButtonFragmentInteraction(int sectionNumber, String cardNo) {
// TODO: Add point for given card number
int points = 5; //sample points
AddPointsSuccessFragment addPointsSuccessFragment =
new AddPointsSuccessFragment().newInstance(sectionNumber, cardNo, points);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, addPointsSuccessFragment)
.addToBackStack(null)
.commit();
}
Фрагмент кода для создания Frag3
public void onOkButtonFragmentInteraction(int sectionNumber, String cardNo, int points) {
RedeemRewardFragment redeemRewardFragment =
new RedeemRewardFragment().newInstance(sectionNumber, cardNo, points);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, redeemRewardFragment);
fragmentTransaction.commit();
}
Мой текущий обходной путь для этого, добавив .addToBackStack(null)
в создании Frag3 и запуске этого кода
public void onBackButtonFragmentInteraction() {
this.onBackPressed(); // simulate pressing of activity back button
FragmentManager fragmentmanager = getFragmentManager();
fragmentmanager.popBackStack(); // pop Frag2 from back stack
}
сразу после вызова метода onBackPressed(). К сожалению, этот обходной путь уродлив, потому что перед тем, как перейти к Frag1, Frag2 появляется в доли секунды.
3 ответа
Итак, ключ к вашему решению вот этот парень:
.addToBackStack(null)
Вместо нуля вы можете передать идентификатор String для этой конкретной транзакции - например, имя класса Fragment - это то, что мы используем (хотя это не сработает, если у вас есть несколько экземпляров одного и того же фрагмента в backstack):
.addToBackStack(Fragment1.class.getName())
Затем, если вы хотите вернуться к Fragment1
от Fragment3
просто вставьте, используя идентификатор следующего фрагмента, и передайте INCLUSIVE
флаг (это означает, что он также выскочит следующий указанный вами фрагмент):
getFragmentManager().popBackStack(
Fragment2.class.getName(),
FragmentManager.POP_BACK_STACK_INCLUSIVE);
Который будет воспроизводить ваши анимации, как ожидалось, но как будто фрагменты между ними никогда не были там. Причина, по которой я предлагаю использовать следующий фрагмент, заключается в том, что вам, вероятно, не нужна первая транзакция фрагмента в обратном стеке.
Вы можете попробовать это, это должно работать и не дает доли секунды. Хотя это не красивый код, и если у кого-то есть лучший способ, пожалуйста, пишите.
1. Присвойте тег своим фрагментам.
transaction.add(R.id.main_activity_container, FirstFragment, "FirstFragment");
transaction.replace(R.id.main_activity_container, Second, "SECOND");
transaction.replace(R.id.main_activity_container, Third, "THIRD");
2. Модифицируйте свой onBackPressed() в своей фрейм-активности (активности), которая "размещает" ваши фрагменты.
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
int lastStack = getSupportFragmentManager().getBackStackEntryCount();
try {
//If the last fragment was named/tagged "three"
if (getSupportFragmentManager().getFragments().get(lastStack).getTag().equalsIgnoreCase("THIRD")){
getSupportFragmentManager().popBackStackImmediate();
getSupportFragmentManager().popBackStackImmediate();
//Get your first fragment that you loaded in the beginning.
Fragment first = getSupportFragmentManager().findFragmentByTag("FirstFragment");
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.main_activity_container, first);
transaction.commit();
return;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onBackPressed();
}
При отображении Frag2 используйте:
final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.addToBackStack(FRAG_2);
fragmentTransaction.replace(containerID, frag2, FRAG2_TAG);
и на спине нажмите:
@Override
public void onBackPressed() {
final Frag2 frag2 = (Frag2)getSupportFragmentManager().findFragmentByTag(FRAG2_TAG);
if (frag2 != null && frag2.isVisible() && getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStackImmediate();
return;
}
}
Это предотвратит отображение frag2 после вызова onBackPressed(). Избегайте использования popBackStack(), так как это приведет к триггеру жизненного цикла frag2 (onCreate, onStart, onResume ...)