我可以先将一个片段添加到视图中,然后“分离”它,然后将其“重新附加”到另一个视图吗?
在代码中,我想:
fragOne one = new fragOne();
getSupportFragmentManager().beginTransaction()
.add(R.id.left, one, "tag").commit();
getSupportFragmentManager().beginTransaction()
.detach(one).commit(); // or .remove(), or .addToBackStack(null).remove()
getSupportFragmentManager().executePendingTransactions();
getSupportFragmentManager().beginTransaction()
.add(R.id.right, one).commit();
但它会引发错误:
04-05 13:28:03.492: E/AndroidRuntime(7195): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.trybackstack/com.example.trybackstack.MainActivity}: java.lang.IllegalStateException: Can't change container ID of fragment fragOne{40523130 #0 id=0x7f080000 tag}: was 2131230720 now 2131230721
感谢您的帮助!
答案 0 :(得分:13)
我有同样的问题,但我发现我真正需要的是重新显示片段的视图而不是片段本身,从而避免任何fragmentManager事务。
View vv = fragment.getView();
ViewGroup parent = (ViewGroup)vv.getParent();
parent.removeView(vv);
newparent.addView(vv, layoutParams);
答案 1 :(得分:11)
第一个问题 - 在尝试将片段添加到另一个容器之前,您必须提交并执行删除事务。感谢您访问nave's answer
但这并不是每次都有用。第二个问题是后台堆栈。它以某种方式阻止了交易。
所以对我有用的完整代码如下:
manager.popBackStackImmediate(null, manager.POP_BACK_STACK_INCLUSIVE);
manager.beginTransaction().remove(detailFragment).commit();
manager.executePendingTransactions();
manager.beginTransaction()
.replace(R.id.content, masterFragment, masterTag)
.add(R.id.detail, detailFragment, activeTag)
.commit();
答案 2 :(得分:8)
我想你现在已经想到了这个,但我没有看到任何令人满意的答案。 所以,我将这个发布给其他可能会在未来引用它的人。
如果要将片段从一个视图移动到另一个视图,请执行以下操作:
android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragment1);
fragmentTransaction.commit();
fragmentManager.executePendingTransactions();
fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.containerToMoveTo, fragment1);
fragmentTransaction.commit();
这样您就不必复制片段了。
答案 3 :(得分:2)
请检查解决方案,如果要保存旧片段的状态,则需要创建相同片段的新实例并使用旧片段的状态对其进行实例化。
FragmentTransaction ft = mFragmentManager.beginTransaction();
ft.remove(one);
Fragment newInstance = fetchOldState(one);
ft.add(R.id.right, newInstance);
ft.commit();
//TO fetch the old state
private Fragment fetchOldState(Fragment f)
{
try {
Fragment.SavedState oldState= mFragmentManager.saveFragmentInstanceState(f);
Fragment newInstance = f.getClass().newInstance();
newInstance.setInitialSavedState(oldState);
return newInstance;
}
catch (Exception e) // InstantiationException, IllegalAccessException
{
}
}
答案 4 :(得分:0)
我也遇到过这个问题。有时移动片段有效,有时您必须创建一个新实例。如果片段一直处于“isRemoving”状态,那么移动片段似乎不起作用。 通过在靠背堆中放置一个片段,似乎也可以防止被移除。
答案 5 :(得分:0)
添加到Yan. Yurkin's answer。确保不要将任何转换应用于事务,因为这些似乎会延迟片段的分离。