无论如何交换或重新sorting片段BackStack条目?

我正在创build多个片段应用程序,这需要轻松更改片段选项卡,其BackStack条目必须保留。 用户点击片段必须立即popup。 我认为重新sortingBackStack是最好的select。 有谁知道如何重新订购BackStack?

我有5个片段A,B,C,D,E。 如果用户打开片段如A —> B —> C —> D —> E。 使用默认的背堆栈,回退键工作正常。 但是当用户打开A —> B —> C —> D —> E —> B之后,如果用户点击返回,则默认后退堆栈将转到A.

使用不可滑动的viewpager和addOnPageChangeListener创build数组列表并保存所有打开的页面。 onBackPressed将比较数组列表和显示页面。

用户沿着pathA ---> B ---> C ---> D ---> E然后他想要到达B 所以你应该做的是:

  • 检查B是否已经在后退堆栈中。
  • 如果有,则popBackStackImmediate返回B
  • 如果不存在,则正常添加片段B

所以replace片段应该是这样的:

 public void replaceFragment(Fragment fragment) { String fragmentTag = fragment.getClass().getCanonicalName(); //unique name for the fragment, which will be used as tag. FragmentManager fragmentManager = getSupportFragmentManager(); boolean isPopped = fragmentManager.popBackStackImmediate(fragmentTag, 0); // trying to return to the previous state of B if it exists. if (!isPopped && fragmentManager.findFragmentByTag(fragmentTag) == null){ // fragment is not in the backstack, so create it. FragmentTransaction ft = fragmentManager.beginTransaction(); ft.replace(R.id.frame_layout, fragment, fragmentTag); ft.addToBackStack(fragmentTag); ft.commit(); } } 

请记住,这将返回到B以前的状态

提示:因为你不需要任何片段的两个实例,所以尝试创build它们的单例实例。 因为,如果您正在创build片段的新实例,并且该片段已经存在于后端堆栈中,则新实例将被忽略(因为您正在返回到之前的状态)。

这个用例没有api,但还有其他方法可以这样做:

FragmentBackStackModifyActivity

只需将此代码放置在MainActivity中即可

  @Override public void onBackPressed() { DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); if (drawer.isDrawerOpen(GravityCompat.START)) { drawer.closeDrawer(GravityCompat.START); } else { //super.onBackPressed(); if (getFragmentManager().getBackStackEntryCount() == 1) { finish(); } getFragmentManager().popBackStack(); } } 

这里getFragmentManager().getBackStackEntryCount() == 0将检查堆栈条目是否为0,如果它是0,那么Activity将完成。

在你的情况下,A – > B – > C – > D – > E – > B

A会0,
乙将在1,
C 2,
D 3,
E 4日,
B 5

所以当你点击后面时, if条件将检查后台计数是否为0。

你可以试试这个…

onBackpressed

  @Override public void onBackPressed() { Fragment f = getSupportFragmentManager().findFragmentById(R.id.frame_container); if (f instanceof FragmentE) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.popBackStack(fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount()-1).getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE); } else if (f instanceof FragmentD) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.popBackStack(fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount()-2).getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE); } else if (f instanceof FragmentC) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.popBackStack(fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount()-3).getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE); } else if (f instanceof FragmentB) { FragmentManager fragmentManager = getFragmentManager(); fragmentManager.popBackStack(fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount()-4).getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE); } else { super.onBackPressed(); } } 

为后面删除堆栈

  final android.app.FragmentManager fm = getFragmentManager(); fm.addOnBackStackChangedListener(new android.app.FragmentManager.OnBackStackChangedListener() { @Override public void onBackStackChanged() { if (getSupportFragmentManager().getBackStackEntryCount() ==0) { // dLayout.closeDrawers(); finish(); } else { // dLayout.closeDrawers(); } } }); 

只有在片段不被添加之前,才可以调用addToBackstack()

假设你的情况,当用户在片段E和用户调用片段B时,检查片段B是否已经添加回栈

如果是,那么不要为那个FragmentTransaction调用addToBackstack。

否则,调用addToBackstack()

检查我的示例代码:

  private void addFragment (Fragment fragment){ boolean isFragment=false; String backStateName = fragment.getClass().getName(); FragmentManager fm = getFragmentManager(); for(int entry = 0; entry < fm.getBackStackEntryCount(); entry++){ Log.i(TAG, "Found fragment: " + fm.getBackStackEntryAt(entry).getId()); if(fm.getBackStackEntryAt(entry).getId().equalsIgnoreCase(FragmentB))// check if fragment is in back stack { isFragment=true; } } if (!isFragment){ //fragment added to back stack, create it. getSupportFragmentManager().beginTransaction() .replace(R.id.fragmentContainer, FragmentB).addToBackStack(FragmentB).commit(); }else {//else dont call addToBackStack() getSupportFragmentManager().beginTransaction() .replace(R.id.fragmentContainer, FragmentB).commit(); } }