Android Fragment popFromBackstack()只能运行一次

时间:2015-11-19 17:52:00

标签: android android-fragments

我有两个我正在初始化的片段,并且这样提交....

FragmentA

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

FragmentB

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

FragmentA在应用程序启动时创建并显示,但只有用户点击按钮才会显示FragmentB。

我遇到的问题是......

  1. 片段A在应用程序启动时加载
  2. 用户操作创建片段B;片段B成功显示。
  3. 用户按设备返回按钮,并调用getFragmentManager.popBackStack()。片段A成功显示。
  4. 用户操作再次创建片段B;片段B成功显示。
  5. 用户按设备返回按钮,并调用getFragmentManager.popBackStack()应用程序崩溃,出现以下错误:

    java.lang.IllegalStateException: Fragment already added: FragmentB{3c73b216 #2 id=0x7f0f00c6}
    
  6. 我在最后一天拉着我的头发试图找出为什么交易和后台弹出工作一次,但第二次崩溃。我尝试过使用add()replace()remove()等各种组合,但情况会变得更糟。我当前崩溃的实现是我得到的最接近的。

2 个答案:

答案 0 :(得分:3)

设置第一个片段:

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

<小时/>

使用此函数替换片段以避免一遍又一遍地添加相同的片段到堆栈:

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

}

执行示例:

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

<小时/>

覆盖onBackPressed

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

答案 1 :(得分:1)

在您调用FragmentA的活动中, 这样做:

@Id
@Column(name="INFO_ID", insertable=false)
private int infoId;

@OneToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name="INFO_ID")
private PARENT parent;

和R.id.filter_fragment应该是活动的布局,它将托管片段的布局。