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

时间:2016-09-08 01:10:13

标签: android android-fragments instance fragment-backstack

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

我有5个片段A,B,C,D,E。如果用户打开片段,如A ---> B ---> C ---> D ---> E.使用默认的后栈,后退键可以正常工作。但是当用户打开A ---> B ---> C ---> D ---> E ---> B.此后,如果用户单击后退,则默认后退堆栈将转到A.

6 个答案:

答案 0 :(得分:1)

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

实施例

FragmentBackStackModifyActivity

答案 1 :(得分:1)

用户遵循路径A ---> B ---> C ---> D ---> E然后他想来B。所以你应该做的是:

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

所以替换片段应该是这样的:

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以前的状态

提示:由于您不想要任何片段的两个实例,因此请尝试创建它们的单例实例。因为,如果要创建片段的新实例并且该片段已存在于后台堆栈中,则将忽略新实例(因为您将返回到先前的状态)。

答案 2 :(得分: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();

 }
}
  

for back remove stack

 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();

            }
        }
    });

答案 3 :(得分:0)

只有在

之前没有添加片段时才可以调用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();
        }
    }

答案 4 :(得分:0)

只需将此代码放入MainActivity

即可
public string ImageToBase64(Image image,
      System.Drawing.Imaging.ImageFormat format)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            // Convert Image to byte[]
           image.Save(ms, format);
            byte[] imageBytes = ms.ToArray();

            // Convert byte[] to Base64 String
            string base64String = Convert.ToBase64String(imageBytes);
            return base64String;
        }
    }

此处 @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(); } } 将检查堆栈条目是否为0,如果它为0,则活动将完成。

在你的情况下A - &gt; B - &gt; C - &gt; D - &gt; E - &gt; B

A将在0,
B将在1,
C on 2,
D on 3,
E on 4,
B on 5

因此,当您单击后面时,getFragmentManager().getBackStackEntryCount() == 0条件将检查后端堆栈计数是否为0。

答案 5 :(得分:0)

使用不可转换的viewpager并在addOnPageChangeListener上创建arraylist并保存打开的所有页面。 onBackPressed将比较arraylist和show pages。