DroidLearner
DroidLearner

Reputation: 2135

Fatal Exception: The specified child already has a parent

I was following Android Youtube Api (ListVideos) which is in Activity. I'm trying this in Fragment and I'm getting FATAL EXCEPTION The specified child already has a parent. You must call removeView() on the child's parent first. I gone through some answers posted by others. It couldn't help me. Could anyone tell me where I have to remove view?

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.video_list_demo, container, true);

    listFragment = (VideoListFragment) getActivity().getFragmentManager()
            .findFragmentById(R.id.list_fragment);
    videoFragment = (VideoFragment) getActivity().getFragmentManager()
            .findFragmentById(R.id.video_fragment_container);

    videoBox = view.findViewById(R.id.video_box);
    closeButton = view.findViewById(R.id.close_button);

    videoBox.setVisibility(View.INVISIBLE);

    layout();

    return view;

}

xml:

<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<fragment
    android:id="@+id/list_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.youtube.VideoListDemoActivity$VideoListFragment" />

<LinearLayout
    android:id="@+id/video_box"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:orientation="vertical" >

    <ImageButton
        android:id="@+id/close_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:onClick="onClickClose"
        android:src="@android:drawable/btn_dialog" />

    <fragment
        android:id="@+id/video_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        class="com.youtube.VideoListDemoActivity$VideoFragment" />
</LinearLayout>
 </merge>

layout():

    private void layout() {
    boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;

    listFragment.getView().setVisibility(
            isFullscreen ? View.GONE : View.VISIBLE);
    listFragment.setLabelVisibility(isPortrait);
    closeButton.setVisibility(isPortrait ? View.VISIBLE : View.GONE);

    if (isFullscreen) {
        videoBox.setTranslationY(0); 
        setLayoutSize(videoFragment.getView(), MATCH_PARENT, MATCH_PARENT);
        setLayoutSizeAndGravity(videoBox, MATCH_PARENT, MATCH_PARENT,
                Gravity.TOP | Gravity.LEFT);
    } else if (isPortrait) {
        setLayoutSize(listFragment.getView(), MATCH_PARENT, MATCH_PARENT);
        setLayoutSize(videoFragment.getView(), MATCH_PARENT, WRAP_CONTENT);
        setLayoutSizeAndGravity(videoBox, MATCH_PARENT, WRAP_CONTENT,
                Gravity.BOTTOM);
    } else {
        videoBox.setTranslationY(0); 
        int screenWidth = dpToPx(getResources().getConfiguration().screenWidthDp);
        setLayoutSize(listFragment.getView(), screenWidth / 4, MATCH_PARENT);
        int videoWidth = screenWidth - screenWidth / 4
                - dpToPx(LANDSCAPE_VIDEO_PADDING_DP);
        setLayoutSize(videoFragment.getView(), videoWidth, WRAP_CONTENT);
        setLayoutSizeAndGravity(videoBox, videoWidth, WRAP_CONTENT,
                Gravity.RIGHT | Gravity.CENTER_VERTICAL);
    }
}

logcat:

02-18 22:18:56.431: E/AndroidRuntime(7936): FATAL EXCEPTION: main
02-18 22:18:56.431: E/AndroidRuntime(7936): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.view.ViewGroup.addViewInner(ViewGroup.java:3389)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.view.ViewGroup.addView(ViewGroup.java:3260)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.view.ViewGroup.addView(ViewGroup.java:3205)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.view.ViewGroup.addView(ViewGroup.java:3181)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:931)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.os.Handler.handleCallback(Handler.java:615)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.os.Handler.dispatchMessage(Handler.java:92)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.os.Looper.loop(Looper.java:137)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at android.app.ActivityThread.main(ActivityThread.java:4895)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at java.lang.reflect.Method.invokeNative(Native Method)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at java.lang.reflect.Method.invoke(Method.java:511)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
02-18 22:18:56.431: E/AndroidRuntime(7936):     at dalvik.system.NativeStart.main(Native Method)

Upvotes: 2

Views: 516

Answers (1)

Leonidos
Leonidos

Reputation: 10518

change

inflater.inflate(R.layout.video_list_demo, container, true);

to

inflater.inflate(R.layout.video_list_demo, container, false);

and read documentation why*.

*you must not attach fragment's view by yourself. You should only return it. And you can't use merge in this case because you can't return not attached merged view. FragmentManager will decide when to attach and remove fragment's view.

Upvotes: 3

Related Questions