Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error using the RecyclerView: The specified child already has a parent

I am trying to create a listView with a new RecyvlerView Adapter. I have followed the exact guide present on android developer resources. But this is giving me a strange error: The specified child already has a parent. You must call removeView() on the child's parent first. I have the latest SDK. I also define dependencies in gradle.

MyActivity (Main Activity):

public class MyActivity extends Activity {

    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        mRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

        // specify an adapter (see also next example)
        mAdapter = new MyAdapter(new String[]{"Zain", "Nadeem"});

        mRecyclerView.setAdapter(mAdapter);
    }
}

MyAdapter :

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private String[] mDataset;    
    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // create a new view
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());  

        View v = inflater.inflate(R.layout.my_text_view, parent, true);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element    
        holder.mTextView.setText(mDataset[position]);
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public ViewHolder(View v) {
            super(v);
            mTextView = (TextView) v.findViewById(R.id.item_title);
        }
    }
}

my_text_view.xml (layout for list items):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="80dp"

    >
    <!-- title -->
    <TextView
        android:id="@+id/item_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/darker_gray"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="8dp"
        android:textSize="22dp" />

</RelativeLayout>

activity_my.xml (main activity):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:background="@android:color/holo_orange_light"
    >
    <!-- A CardView that contains a TextView -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MyActivity"/>
    </LinearLayout>

And here is the logcat output:

10-28 01:20:30.287  22729-22729/osman.zaingz.com.lollipop E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: osman.zaingz.com.lollipop, PID: 22729
    java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
            at android.view.ViewGroup.addViewInner(ViewGroup.java:3562)
            at android.view.ViewGroup.addView(ViewGroup.java:3415)
            at android.view.ViewGroup.addView(ViewGroup.java:3360)
            at android.support.v7.widget.RecyclerView$4.addView(RecyclerView.java:322)
            at android.support.v7.widget.ChildHelper.addView(ChildHelper.java:79)
            at android.support.v7.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:4845)
            at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:4803)
            at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:4791)
            at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1316)
            at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1265)
            at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:522)
            at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1918)
            at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2155)
            at android.view.View.layout(View.java:14817)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
            at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1660)
            at android.widget.LinearLayout.onLayout(LinearLayout.java:1436)
            at android.view.View.layout(View.java:14817)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
            at android.view.View.layout(View.java:14817)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:374)
            at android.view.View.layout(View.java:14817)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
            at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
            at android.view.View.layout(View.java:14817)
            at android.view.ViewGroup.layout(ViewGroup.java:4631)
            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1983)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1740)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:996)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5600)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
            at android.view.Choreographer.doCallbacks(Choreographer.java:574)
            at android.view.Choreographer.doFrame(Choreographer.java:544)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
like image 955
Zain Zafar Avatar asked Oct 27 '14 20:10

Zain Zafar


3 Answers

when inflating you shouldn't attach the view to its parent. you wrote:

View v = inflater.inflate(R.layout.my_text_view, parent, true);

which should be :

View v = inflater.inflate(R.layout.my_text_view, parent, false);
like image 171
EC84B4 Avatar answered Nov 19 '22 21:11

EC84B4


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="80dp">

<TextView
    android:id="@+id/item_title"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="@android:color/darker_gray"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginTop="8dp"
    android:textSize="22dp" />

</RelativeLayout>

RelativeLayout this is parent of your TextView with id item_title. Then when RecyclerView is trying to add TextView that has parent it throw exception.

Try this code:

public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {
        // create a new view
        Log.d(TAG, "onCreateViewHolder");
        RelativeLayout v = (RelativeLayout)LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item, parent, false);
        // set the view's size, margins, paddings and layout parameters
        View view = v.findViewById(R.id.text1);
        v.removeView(view);
        ViewHolder vh = new ViewHolder(view);
        return vh;
    }
like image 23
Magadan Artem Avatar answered Nov 19 '22 20:11

Magadan Artem


It happens too if you scroll really fast your recyclerview. My case was inserting/moving/... items with DiffUtils and calling TransitionManager.beginDelayedTransition(view) on the root layout (and so, the recyclerview) somewhere in my code before the end of recyclerview animations

like image 16
Victor Avatar answered Nov 19 '22 19:11

Victor