2014-09-16 3 views
10

Я довольно новый с андроидными фрагментами, поэтому, пожалуйста, несите меня.Пропустить некоторые фрагменты onBackPressed

У меня есть куча фрагментов с использованием одного действия в качестве хоста.

На мой взгляд, мои фрагменты сгруппированы по разделам, хотя они по-прежнему являются модульными/многоразовыми по коду. Рассмотрим этот желаемый сценарий:

Frag1 -> (Нажмите Next) -> Frag2 -> (Нажмите Next) -> 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.

ответ

6

Поэтому ключ к вашему решению здесь этот парень:

.addToBackStack(null) 

Вместо нуль, вы можете передать в строковый идентификатор для данной конкретной сделки - например, имя класса из фрагмент, что мы используем (хотя это не сработает, если у вас есть несколько экземпляров одного и того же фрагмента на backstack):

.addToBackStack(Fragment1.class.getName()) 

Затем, если вы хотите, чтобы вернуться сюда Fragment1 м Fragment3, просто выскочить с использованием идентификатора следующего фрагмента, и передать INCLUSIVE флаг (который означает, что он будет также поп, что следующий фрагмент, который вы указали):

getFragmentManager().popBackStack(
     Fragment2.class.getName(), 
     FragmentManager.POP_BACK_STACK_INCLUSIVE); 

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

+0

Я попробовал ваше предложение, но, к сожалению, на экране все еще отображается Frag2 в течение секунды, прежде чем вернуться в Frag1 , Я также добавил фрагмент кода для Frag1 для лучшей перспективы. :( –

+2

После дальнейших экспериментов я узнал, что после реализации вашего предложения я больше не должен называть this.onBackPressed(). И теперь он работает «... как будто фрагментов между ними никогда не было». Спасибо !;) –

+0

Я следил за тем же, но он не работает для меня. Можете, пожалуйста, проверить, что я делаю неправильно здесь. Http://stackoverflow.com/questions/31118973 – pyus13

1

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

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.Modify ваш onBackPressed() в frameActivity (деятельности), что "дома" ваших фрагментов.

@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(); 
} 
+0

Невзирая на ответ, я попытался реализовать ваше предложение. Хотя мне потребовалось некоторое время для реализации, это определенно сработало! Хотя я все же предпочел бы ответ @ kcoppock, поскольку для меня потребовалось меньше изменений кода и меньше беспорядка. И все же, плюс для вас, для того, чтобы дать мне еще одну идею! :) –

+0

Да, ответ kcoppock, вероятно, лучший в этом случае, выглядит намного чище. Возможно, я перейду на аналогичное решение в своем приложении: P. Хотя они могут работать по-другому? Как он себя ведет, если вы идете: Frag1 -> Frag2 -> Frag3 -> BackBtn, чем BackBtn снова, выходит ли он или вы переходите на Frag2 – user3711421

+0

Если вы имеете в виду предложение kcoppock, то он выходит из приложения, так как он следил за потоком, который я желательно. Frag1 -> Далее -> Frag2 -> Далее -> Frag3 -> Назад -> Frag1 -> Назад -> EXIT –

0

При отображении 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 ...)

Смежные вопросы