Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ViewHolder parameter from RecyclerView#onCreateViewHolder differents

Tags:

android

This is the sample code I followed.

And the code below is the part of onCreateViewHolder in the sample code:

@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                               int viewType) {
    // create a new view
    View v = LayoutInflater.from(parent.getContext())
                           .inflate(R.layout.my_text_view, parent, false);
    // set the view's size, margins, paddings and layout parameters
    ...
    ViewHolder vh = new ViewHolder(v);
    return vh;
}

And this is the part of ViewHolder:

public static class ViewHolder extends RecyclerView.ViewHolder {
    public TextView mTextView;
    public ViewHolder(TextView v) {
        super(v);
        mTextView = v;
    }
}

Obviously, the parameter TextView v is wrong.

Then I play a trick in the onCreateViewHolder method like this:

    ...
    TextView textView = (TextView) v.findViewById(R.id.tv_test);
    ViewHolder vh = new ViewHolder(textView);

But I got an Exception when I run the app.

    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:3693)
        at android.view.ViewGroup.addView(ViewGroup.java:3546)
        at android.view.ViewGroup.addView(ViewGroup.java:3491)
        at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:3533)
        at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:3558)
        at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1012)
        at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:524)
        at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1461)
        at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:1600)
        at android.view.View.layout(View.java:15273)
        at android.view.ViewGroup.layout(ViewGroup.java:4763)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1069)
        at android.view.View.layout(View.java:15273)
        at android.view.ViewGroup.layout(ViewGroup.java:4763)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:457)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:392)
        at android.view.View.layout(View.java:15273)
        at android.view.ViewGroup.layout(ViewGroup.java:4763)
        at com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:494)
        at android.view.View.layout(View.java:15273)
        at android.view.ViewGroup.layout(ViewGroup.java:4763)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:457)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:392)
        at android.view.View.layout(View.java:15273)
        at android.view.ViewGroup.layout(ViewGroup.java:4763)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2057)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1814)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1044)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5749)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:550)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:738)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5070)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631)

BUT when I change the ViewHolder code like this:

    public ViewHolder(View v) {
        super(v);
        mTextView = (TextView) v;
    }

It will be OK.

I want to know what this Exception means? What happened to make this Exception?

like image 247
callofdutyops Avatar asked Aug 29 '14 18:08

callofdutyops


1 Answers

I stumbled accross the same sample and was shortly confused, too. The View that is passed to the ViewHolder constructor is the inflated parent View that contains all your Views of one list item. Use this passed View to initialise all the fields of the ViewHolder in its constructor like this:

public class MyViewHolder extends RecyclerView.ViewHolder  {

    public TextView titleWithIcon;
    public TextView teaser;        

    public MyViewHolder(View itemView) {
        super(itemView);
        
        titleWithIcon = (TextView) itemView.findViewById(R.id.title_with_icon);
        teaser = (TextView) itemView.findViewById(R.id.teaser);
    }
}
like image 120
muetzenflo Avatar answered Sep 30 '22 15:09

muetzenflo