14

这是负责将片段添加到后台堆栈的函数:

public void populateContent(File f)
{

    ContentFragment cf = new ContentFragment(ctx, ac, this);
    FragmentTransaction transaction = ac.getSupportFragmentManager().beginTransaction();;
    cf.updateView(f);

    transaction.replace(R.id.contentFragment, cf);

    transaction.addToBackStack(null);

    transaction.commit();

}

当我单击后退按钮时,最后一个片段没有被加载(没有任何反应)。

知道可能是什么原因造成的吗?

编辑:片段管理器日志。

http://pastebin.com/mYnVdkLG

在我看来,好像我的应用程序正在保存第二个视图两次,而不是保存第一个视图然后保存第二个视图。

4

3 回答 3

54

似乎在片段事务上调用 addToBackStack() 是不够的,我们必须处理自己按下返回按钮时弹出返回堆栈。我将此添加到我的活动中,它按预期工作:

@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0 ){
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}
于 2014-10-28T03:29:40.900 回答
12

我不确定实际的解决方案,但我可以为您提供一些指导,也许您可​​以找出问题所在。

您实际上是在替换两个片段吗?如果您不这样做,则没有交易可恢复。也是你第一次Fragment从 XML 添加?经理不会知道这个片段,您可能还需要Fragment使用事务添加第一个片段。

小心检查,if (savedInstanceState == null) performFirstTransaction()否则你最终会添加你的第一个Fragment两次。

一个好主意是enableDebugLoggingFragmentManager. 这将告诉您经理知道哪些片段。

看到这个: http: //developer.android.com/reference/android/app/FragmentManager.html#enableDebugLogging(boolean)

作为旁注,不建议为您的Fragment. 那是因为如果您的应用程序被操作系统杀死并重新实例化,它将调用空构造函数。

您应该使用静态方法,例如ContentFragment.getInstance(<params>)创建您的Fragment.

在“类概述”部分查看更多信息: http: //developer.android.com/reference/android/app/Fragment.html 。

我希望我的回答可以帮助您找到问题所在。

于 2013-02-11T06:43:29.783 回答
2

我是在添加,而不是替换,但我必须在 add() 之前调用 addToBackStack(null),而不是之后,在将关闭的片段上,而不是在将保持打开的片段上。

A类(先开)

FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.layout_a, f, Constants.FRAGMENT_KEY);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();

B级(A级开)

FragmentTransaction ft = fm.beginTransaction();
ft.addToBackStack(null);
ft.add(R.id.layout_b, f, Constants.FRAGMENT_KEY);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
于 2015-02-19T16:19:03.820 回答