Android - addToBackStack()不起作用?

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

}

当我点击后退按钮时,上一个片段没有加载(什么也没有发生)。

您有什么想法是什么原因造成的?

编辑:FragmentManager日志。

http://pastebin.com/mYnVdkLG

我觉得我的应用程序似乎保存了第二个视图两次,而不是先保存第一个视图,然后再保存第二个视图。


我认为你应该先使用addtobackStack(),然后再替换fragment... - user1969053
我确实尝试过这个,并将以下方法添加到我的Activity中 - 但没有起作用。http://pastebin.com/aezQD48p - Tool
问题可能是我使用了SupportManager而不是Manager吗?我可以看到你链接的问题与ChildFragmentManager有关 - 我的是SupportManager。 - Tool
实际上,addToBackStack(null) 不适用于 Fragment 和 AppCompatActivity。但是它适用于 v4 版本的 Fragment 和 AppCompatActivity(已验证)。 - deadfish
3个回答

54

似乎在Fragment事务中调用addToBackStack()并不足够,我们还需要自己处理后退按钮按下时的返回栈弹出。我将其添加到我的Activity中,效果符合预期:

@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0 ){
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}

4
这个方法可行,但不会重复播放动画。编辑:如果你想在弹出栈时播放动画,请在调用setCustomAnimation时添加两个额外参数。详见这里 - Nathan
2
这个很好用。令人惊讶的是我们必须自己处理它,因为我猜文档上说这应该会自动发生。 - Ankit
这个是否有文档记录? - Defuera
以前不用它也能工作,但最近遇到了相同的问题,使用这个方法解决了该问题... - Warpzit
如果您的活动从FragmentActivity继承,并且使用getSupportFragmentManager添加事务,则无需执行此操作。 - vdua
你刚刚帮我省去了很多麻烦! - oxyt

12

我不确定实际的解决方案,但是我可以给你一些指导,也许你可以找到问题所在。

你是否实际上替换了两个片段?如果没有,则没有要回滚的事务。同时,你的第一个Fragment是从XML添加的吗?管理器将不知道此片段,你可能也需要使用事务来添加第一个Fragment

请注意检查if(savedInstanceState == null)performFirstTransaction(),否则你将会添加两次第一个Fragment

一个好的主意是在FragmentManager中使用enableDebugLogging。这将告诉你有关管理器已知的哪些片段。

请参阅: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 的“类概述”部分。

我希望我的答案能帮你一点点找到问题所在。


另外,我的Fragment没有自定义构造函数 - 我没有更改它。但是,我在Fragment中有一个作为视图更新器的方法。 - Tool
好的,我已经从管理员那里发布了日志链接。 - Tool

2

我进行的是添加操作而不是替换操作,但在将要关闭的片段上调用addToBackStack(null),而不是在将保持打开状态的片段上调用add()之后。

在A类中(首先打开)

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

在A类中打开的B类

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

在执行片段的添加/替换时,使用addToBackStack对我很有帮助。 - Clocker
请在add()之前调用addToBackStack(null),而不是之后。这正是我的问题所在。你帮我解决了很多麻烦。谢谢! - Gautham C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接