简体   繁体   English

Android片段popFromBackstack()仅可运行一次

[英]Android Fragment popFromBackstack() only works once

I've got two fragments that I am initializing, and committing like so.... 我有两个正在初始化的片段,并像这样提交....

FragmentA 片段A

    getFragmentManager().beginTransaction()
            .add(R.id.filter_fragment, fragmentA)
            .commit();

FragmentB 片段B

    getFragmentManager().beginTransaction()
            .replace(R.id.filter_fragment, fragmentB)
            .addToBackStack(null)
            .commit();

FragmentA is created and shown on application start, but FragmentB is not shown until a button is clicked by the user. FragmentA已创建并在应用程序启动时显示,但FragmentB在用户单击按钮之前不会显示。

The issue that I am having is this... 我遇到的问题是...

  1. Fragment A loaded at application start 在应用程序启动时加载的片段A
  2. User action creates Fragment B; 用户操作创建片段B; Fragment B shown successfully. 片段B显示成功。
  3. User presses device back button, and getFragmentManager.popBackStack() is called. 用户按下设备后退按钮,将调用getFragmentManager.popBackStack() Fragment A shown successfully. 片段A显示成功。
  4. User action creates Fragment B again; 用户操作再次创建片段B; Fragment B shown successfully. 片段B显示成功。
  5. User presses device back button, and getFragmentManager.popBackStack() is called. 用户按下设备后退按钮,将调用getFragmentManager.popBackStack() Application crash with the following error: 应用程序崩溃,出现以下错误:

     java.lang.IllegalStateException: Fragment already added: FragmentB{3c73b216 #2 id=0x7f0f00c6} 

I've been pulling my hair out for the last day trying to figure out why the transactions and backstack pops work one time, but crash the second time. 在过去的一天中,我一直在努力工作,以弄清为什么事务和回栈弹出一次起作用,而第二次却崩溃。 I've tried playing around with various combinations of add() , replace() , remove() , etc, and it only gets worse. 我尝试过使用add()replace()remove()等各种组合,但情况只会变得更糟。 My current crashing implementation is the closest I have gotten. 我当前崩溃的实现是我得到的最接近的实现。

Set first fragment: 设置第一个片段:

if (null == savedInstanceState) {
    getSupportFragmentManager().beginTransaction().addToBackStack("fragmentA").replace(R.id.container, new FragmentA(), "CURRENT_FRAGMENT_TAG").commit();
}

in OnCreate in your activity 在您的活动中的OnCreate


Use this function to replace fragments to avoid adding same fragment over and over again to stack: 使用此函数替换片段,以避免一遍又一遍地将相同的片段添加到堆栈中:

public void replaceFragment(Fragment fragment, String tag) {
    Fragment currentFragment = getSupportFragmentManager().findFragmentByTag("CURRENT_FRAGMENT_TAG");

    //to avoid adding the same fragment, you can use 'instanceof' instead of comparator
    if (currentFragment.getClass() == fragment.getClass()) {
        return;
    }
    getSupportFragmentManager().popBackStack(tag, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    getSupportFragmentManager()
            .beginTransaction()
            .addToBackStack(tag).replace(R.id.container, fragment, "CURRENT_FRAGMENT_TAG")
            .commit();

}

Example execution: 执行示例:

replaceFragment(new FragmentB(), "fragmentB");


Override onBackPressed . 覆盖onBackPressed

@Override
public void onBackPressed() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
        finish();
    } else {
        super.onBackPressed();
    }
}

On your activity that calls FragmentA, do this: 在调用FragmentA的活动上,执行以下操作:

getFragmentManager().beginTransaction() 
        .replace(R.id.filter_fragment, fragmentA)
        .commit();

and the R.id.filter_fragment, should be the layout from the activity which will host the fragments' layouts. R.id.filter_fragment应该是来自活动的布局,它将托管片段的布局。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM