8

这是我希望我的应用程序在平板电脑上执行的操作。片段 (0) 有一些菜单可以显示片段 (1)...(n),如下所示:

-----------------
|   |   |   |   |
|   |   |   |   |
|(0)| X | X | X |
|   |   |   |   |
|   |   |   |   |
-----------------
 becomes
-----------------
|   |   |   |   |
|   |   |   |   |
|(0)|(1)| X | X |
|   |   |   |   |
|   |   |   |   |
-----------------
 and then
-----------------
|   |   |   |   |
|   |   |   |   |
|(0)|(2)|(1)| X |
|   |   |   |   |
|   |   |   |   |
-----------------
 etc... 

Fragment0 从不移动,其他的都向右移动。离开右侧边缘的碎片将被销毁。

因此,我使用水平 LinearLayout 设置了我的 XML 布局,并包含 4 个具有正确 ID 的 FrameLayout(fragment0...fragment3)

我可以实例化并显示fragment0,然后显示fragment1,但之后我无法将其向右移动,我得到:

ERROR/AndroidRuntime(343): FATAL EXCEPTION: main
java.lang.IllegalStateException: Can't change container ID of fragment ...

我发现的唯一相关问题是这个那个,尝试了所有不同的解决方案,但没有运气。

尝试,FragmentTransaction.remove()然后.add()尝试.replace(),以不同的顺序尝试它们并在中途提交(甚至尝试按照某人的建议提交两次),尝试调用addToBackStack()......仍然没有运气。

问题是是否可以像这样使用 FragmentTransaction 移动片段。如果是的话,我做错了什么(还有奖金,是否可以制作动画?)。如果不是,那么实现这一点的正确方法是什么?

请注意,我不想每次都重新实例化片段(每个片段都会在网络上进行一些可能需要一些时间的查询)。可以将所有数据提取回活动以重新创建一个,但如果可能的话,我宁愿不这样做......

4

2 回答 2

24

是的,可以使用remove()函数更改片段的容器。

这里的问题是commit()。这是一个异步调用,并将其安排在主线程上。FragmentManager因此,在将其添加到另一个容器之前立即强制执行此操作。

为此,我们将不得不使用executePendingTransactions()函数。调用此方法后,尝试将片段添加到新容器中。

文档:executePendingTransactions()

代码示例:

FragmentManager fManager = getSupportFragmentManager();
FragGroups fragGroups = (FragGroups) fManager.findFragmentByTag("groups");
if (fragGroups != null) {
     fManager.beginTransaction().remove(fragGroups).commit();
     fManager.executePendingTransactions();
} else {
     fragGroups = new FragGroups();
}
if (mTwoPane) {
    fManager.beginTransaction().replace(R.id.fragment_container_groups, fragGroups, "groups").commit();
} else {
    fManager.beginTransaction().replace(R.id.fragment_container, fragGroups, "groups").commit();
}

享受。欢迎反馈

编辑

我想在这里补充一点。由于我有同样的问题,遇到了这个线程并应用了建议的更改。问题仍然存在。然后我查看了该线程的最后一条评论,解决了我的问题:addToBackStack()在提交事务时删除方法,或者如果您有意使用它,请在将片段添加到另一个容器之前从后台堆栈中删除片段。希望对以后的读者有所帮助。

于 2013-10-04T09:33:00.483 回答
3

我不知道这是否正是您想要的,但我就您的问题做了一个小样本。基本上,您将使用布局文件进行正确的移位,每个移位片段都有一个包装容器。代码示例对于答案来说有点大,因此我将其发布到您可以在此处找到的要点中。在该示例中,按每个 的ListFragment项目(片段 1 -> 片段 2 -> 片段 3)以查看行为。

于 2012-11-28T15:51:36.730 回答