Android Fragment - 从一个视图移动到另一个视图?

mid*_*ite 9 android android-layout android-fragments android-fragmentactivity fragmenttransaction

我可以先将一个片段添加到视图中,然后"分离"它,然后将其"重新附加"到另一个视图中吗?

在代码中,我想:

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();
Run Code Online (Sandbox Code Playgroud)

但它会引发错误:

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
Run Code Online (Sandbox Code Playgroud)

感谢帮助!

小智 13

我有同样的问题,但我发现我真正需要的是重新定义片段的视图而不是片段本身,从而避免任何fragmentManager事务.

View vv = fragment.getView();
ViewGroup parent = (ViewGroup)vv.getParent();
parent.removeView(vv);
newparent.addView(vv, layoutParams);
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用,因为我想在方向改变时将片段从一个父级移动到另一个父级。所以在方向改变后,片段的宿主视图被破坏。 (2认同)

Yan*_*kin 12

在尝试了类似问题的所有答案后,看起来我已经找到了解决问题的方法.

第一个问题 - 在尝试将片段添加到另一个容器之前,您必须提交执行 remove transaction.谢谢你的回答

但这并不是每次都有效.第二个问题是后台堆栈.它以某种方式阻止了交易.

所以对我有用的完整代码如下:

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();              
Run Code Online (Sandbox Code Playgroud)

  • 这会导致视图被销毁和重新创建,而不是保留 (3认同)

nav*_*ave 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();
Run Code Online (Sandbox Code Playgroud)

这样您就不必复制片段了.

  • 这导致视图被破坏和重建,而不是保留 - 格雷格恩尼斯41秒前编辑 (2认同)

Kar*_*ana 3

请检查解决方案,如果要保存旧片段的状态,则需要创建同一片段的新实例并使用旧片段的状态实例化它。

 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
            {

            }
        }
Run Code Online (Sandbox Code Playgroud)