0

次のレイアウトに 2 つのフラグメントを追加しようとしています。

dialog_empty_linear_layout.xml:

    <LinearLayout
        android:id="@+id/ParentLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:orientation="vertical" >
    </LinearLayout>

</RelativeLayout>

次のコードを使用します。

setContentView(R.layout.dialog_empty_linear_layout);

int parentViewId = getIntent().getIntExtra(PARENT_VIEW_ID, -1); // == R.id.ParentLayout
if (parentViewId == -1)
    parentViewId = android.R.id.content;

/*
 * Extracting Fragments types
 */
Class<? extends Fragment>[] fragmentTypes = getFragments(); // there are two fragments here!

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
for (Class<? extends Fragment> fragmentType  : fragmentTypes) {
    Fragment fragment = Tools.createNewInstance(fragmentType);
    ft.add(parentViewId, fragment);
}
ft.commitAllowingStateLoss();

コードの実行中に、次のエラーが表示されます。

Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

I was quite surprised because this is a newly created Activity, with a newly created fragments and newly created views...

So I've followed the stack trace and checked which child and which parent are we talking about since the exception did not gave any extra info about it...

I was more surprised to find out the Child is the LinearLayout(e.g. R.ParentLayout), and the Parent was the RelativeLayout wrapping it.

Perhaps once again I miss the obvious but I thought that:

ft.add(parentViewId, fragment);

Suppose to add the Fragment to the parentViewId layout, and not to attempt to add the parentViewId layout to its parent layout...

ALSO, if I use the following XML everything works fine:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ParentLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

</LinearLayout>

Any insights?

4

1 に答える 1

0

ええと、それは面白かったです...そして、これに遭遇した人のために...これは非常にばかげていることに注意してください!

Fragment でこのメソッドをオーバーライドします。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_id, container);
}

そして、これが愚かなことです...

inflater.inflate には別のオーバーロードがあります。

    return inflater.inflate(R.layout.fragment_id, container, **addToRoot**);

何らかの理由で、フラグメント レイアウトがコンテナーに追加され(直感を信用しないでください)、コンテナーを rootView に追加しないことを期待していました。今日まで、すべてのフラグメントをルート ビュー (container == rootView) に追加していたので、この問題は発生しませんでしたが、コンテナが rootView ではなくなったら、明示的にaddToRoot =false を指定する必要があります。

    return inflater.inflate(R.layout.fragment_id, container, false);

まあ、それはみんな... ブール値による愚かさです!

于 2013-10-27T13:37:48.010 に答える