2015-06-23 2 views
0

У меня есть активность с тремя фрагментами (A, B и C). Фрагмент A добавляется к активности onCreate, и он также не добавляется к backstack.Отслеживание фрагментов в активности?

навигация поток для этой активности может быть:

А -> В -> С или А -> С

Нажатие назад или navigateUp на фрагменты B или C должен вернуться к предыдущему фрагменту.

Код для добавления фрагментов в деятельности:

private void switchFragment(Fragment fragment, boolean addToBackStack) { 
    FragmentTransaction ft = getFragmentManager().beginTransaction(); 
    ft.replace(R.id.container_fragments, fragment, fragment.getClass().getSimpleName()); 

    if (addToBackStack) { 
     ft.addToBackStack(null); 
    } 

    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 
    ft.commit(); 

    currentFragment = fragment; 
} 

И код, чтобы получить текущий фрагмент:

private Fragment getCurrentFragment(){ 
    FragmentManager fm = getFragmentManager(); 

    if (fm.getBackStackEntryCount() == 0) 
     return null; 

    String tag = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 1).getName(); 

    return getFragmentManager().findFragmentByTag(tag); 
} 

Я перекрывая onBackPressed и onNavigateUp следующим образом:

@Override 
public void onBackPressed() { 
    super.onBackPressed(); 

    currentFragment = getCurrentFragment(); 
    if (currentFragment == null) { 
     currentFragment = fragmentA; 
    } 

    setHeader(); 
} 

@Override 
public boolean onNavigateUp() { 
    if (currentFragment == fragmentA) { 
     return super.onNavigateUp(); 
    } 

    else { 
     getFragmentManager().popBackStack(); 
     currentFragment = getCurrentFragment(); 

     if (currentFragment == null) { 
      currentFragment = fragmentA; 
     } 

     setHeader(); 
     return true; 
    } 
} 

setHeader - это способ изменения заголовок текста операции в зависимости от текущего отображаемого фрагмента.

Вышеуказанные работы, если я перемещаюсь от А до С и назад. Однако для перехода с A на B на C и обратно не работает. Когда вы возвращаетесь с C на B, код думает, что он уже на A (отображается текст заголовка для A), но отображается фрагмент B.

Вышеупомянутый не правильный способ обращения с задней стопой? Что я делаю не так?

+0

просто зарегистрируйтесь onBackPress, что count> 0, чем pop-фрагмент, и напишите код setHeader в onCreateView фрагмента. – Harry

ответ

0

Этот код работает хорошо, вы можете проверить один раз. общественные недействительными pushFragments (строковый тег, фрагмент фрагмент, логический shouldAnimate, логическое shouldAdd) {

if (shouldAdd) 
     mStacks.get(tag).push(fragment); 
    FragmentManager manager = getSupportFragmentManager(); 
    FragmentTransaction ft = manager.beginTransaction(); 
    if (shouldAnimate){ 
     ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left); 
     //Toast.makeText(getApplicationContext(), "Hi", Toast.LENGTH_SHORT).show(); 
     }else{ 
      ft.setCustomAnimations(0, 0); 
     } 

    ft.replace(R.id.frame_container, fragment); 
    ft.commit(); 
// Toast.makeText(getApplicationContext(), "+"+ mStacks.get(mCurrentNavigatorMenu).size(), Toast.LENGTH_LONG).show(); 
} 

public void popFragments() { 
    /* 
    * Select the second last fragment in current tab's stack.. which will 
    * be shown after the fragment transaction given below 
    */ 
    //Toast.makeText(getApplicationContext(), ""+ mStacks.get(mCurrentNavigatorMenu).size(), Toast.LENGTH_LONG).show(); 
    Fragment fragment = mStacks.get(mCurrentNavigatorMenu).elementAt(mStacks.get(mCurrentNavigatorMenu).size() - 2); 

    /* pop current fragment from stack.. */ 
    mStacks.get(mCurrentNavigatorMenu).pop(); 

    /* 
    * We have the target fragment in hand.. Just show it.. Show a standard 
    * navigation animation 
    */ 
    FragmentManager manager = getSupportFragmentManager(); 
    FragmentTransaction ft = manager.beginTransaction(); 
    ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right); 

    ft.replace(R.id.frame_container, fragment); 
    ft.commit(); 
} 


@Override 
public void onBackPressed() { 
    if (((BaseFragment) mStacks.get(mCurrentNavigatorMenu).lastElement()) 
      .onBackPressed() == false) { 
     /* 
     * top fragment in current tab doesn't handles back press, we can do 
     * our thing, which is 
     * 
     * if current tab has only one fragment in stack, ie first fragment 
     * is showing for this tab. finish the activity else pop to previous 
     * fragment in stack for the same tab 
     */ 
     if (mStacks.get(mCurrentNavigatorMenu).size() == 1) { 
      super.onBackPressed(); 
      Intent intent = new Intent(Intent.ACTION_MAIN); 
      intent.addCategory(Intent.CATEGORY_HOME); 
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      startActivity(intent);// or call finish.. 
     } else { 
      popFragments(); 
     } 
    } else { 
     // do nothing.. fragment already handled back button press. 
     Toast.makeText(getApplicationContext(), "Nothing", Toast.LENGTH_LONG).show(); 
    } 
} 
0

Приведенный выше код работает отлично подходит для навигации. Я удалить метод setHeader и переместил его здесь:

final FragmentManager fm = getFragmentManager(); 
    fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { 
     @Override 
     public void onBackStackChanged() { 
      Fragment fr = fm.findFragmentById(R.id.container_fragments); 
      if(fr!=null){ 
       currentFragment = fr; 
       setTitle(); 
      } 
     } 
    }); 

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

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