Groupie: Update README instructions for converting existing ViewHolders

Created on 3 Jan 2018  路  9Comments  路  Source: lisawray/groupie

I'm using trying to convert an existing Java ViewHolder to use with Groupie. In the docs the only thing I can find about this is under the Kotlin section (I'm only sadly using Java and not Kotlin, but the Kotlin section was the only place that mentioned existing ViewHolders) and it says

If you're converting existing ViewHolders, you can leave them as they are by making an Item<MyViewHolder>.

The way I interpret that is that, if I leave my existing ViewHolder alone I should be able to use it seamlessly with Groupie.

public static class MyViewHolder extends RecyclerView.ViewHolder {
        //TextViews and stuff
        public MyViewHolder(View itemView) {
            super(itemView);
           //Butterknife.bind(...)
        }
       //bindTo(){
       //Method recommended by Yigit to be implemented in each VH to handle the actual binding
      //}
}

This existing RecyclerView.ViewHolder lives in MyCustomAdapter.java

Now I go to create my Item since I want to use Groupie.

public class MyItem extends Item<MyCustomAdapter. MyViewHolder>{

    @Override
    public void bind(@NonNull MyCustomAdapter. MyViewHolder viewHolder, int position) {
    //bind
    }

    @Override
    public int getLayout() {
        return R.layout.my_item;
    }
}

I get an error message in the IDE on the first line of the last code snippet (public class MyItem extends Item< MyCustomAdapter. MyViewHolder>{) specifically under <MyCustomAdapter. MyViewHolder> that says

Type parameter com.myapp.MyCustomAdapter.MyViewHolder is not within its bound; should extend com.xwray.groupie.ViewHolder

bug

All 9 comments

Hi, sorry this wasn't clear!

Change MyViewHolder extends RecyclerView.ViewHolder to MyViewHolder extends com.xwray.groupie.ViewHolder.

I also updated the README to be more explicit. Hope that helps!

I'm using 2.0.0-alpha2 for now and changed MyViewHolder to extend from the Groupie Viewholder (as per your previous comment). Then I added groupAdapter.add(new MyItem()); in my Activity. Code compiles which is nice, but now I'm getting another error at runtime.


31357-31357/com.myapp.app E/AndroidRuntime: FATAL EXCEPTION: main
                                                        Process: com.myapp.app, PID: 31357
                                                        java.lang.ClassCastException: com.xwray.groupie.ViewHolder cannot be cast to com.myapp.app.MyCustomAdapter$MyViewHolder
                                                            at com.myapp.app.MyItem.bind(MyItem.java:10)
                                                            at com.xwray.groupie.Item.bind(Item.java:63)
                                                            at com.xwray.groupie.Item.bind(Item.java:49)
                                                            at com.xwray.groupie.GroupAdapter.onBindViewHolder(GroupAdapter.java:89)
                                                            at com.xwray.groupie.GroupAdapter.onBindViewHolder(GroupAdapter.java:19)
                                                            at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6515)
                                                            at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5458)
                                                            at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5724)
                                                            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5563)
                                                            at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5559)
                                                            at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2229)
                                                            at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1556)
                                                            at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1516)
                                                            at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:608)
                                                            at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3693)
                                                            at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3410)
                                                            at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3962)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:610)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                            at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
                                                            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
                                                            at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1172)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                            at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
                                                            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
                                                            at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                            at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
                                                            at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
                                                            at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
31357-31357/com.myapp.app E/AndroidRuntime:     at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                            at com.android.internal.policy.DecorView.onLayout(DecorView.java:758)
                                                            at android.view.View.layout(View.java:19590)
                                                            at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                            at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2484)
                                                            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2200)
                                                            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
                                                            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
                                                            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
                                                            at android.view.Choreographer.doCallbacks(Choreographer.java:723)
                                                            at android.view.Choreographer.doFrame(Choreographer.java:658)
                                                            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
                                                            at android.os.Handler.handleCallback(Handler.java:789)
                                                            at android.os.Handler.dispatchMessage(Handler.java:98)
                                                            at android.os.Looper.loop(Looper.java:164)
                                                            at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                            at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
31357-31357/com.myapp.app E/UncaughtException: java.lang.ClassCastException: com.xwray.groupie.ViewHolder cannot be cast to com.myapp.app.view.MyCustomAdapter$MyViewHolder
                                                               at com.myapp.app.MyItem.bind(MyItem.java:10)
                                                               at com.xwray.groupie.Item.bind(Item.java:63)
                                                               at com.xwray.groupie.Item.bind(Item.java:49)
                                                               at com.xwray.groupie.GroupAdapter.onBindViewHolder(GroupAdapter.java:89)
                                                               at com.xwray.groupie.GroupAdapter.onBindViewHolder(GroupAdapter.java:19)
                                                               at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6515)
                                                               at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5458)
                                                               at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5724)
                                                               at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5563)
                                                               at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5559)
                                                               at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2229)
                                                               at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1556)
                                                               at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1516)
                                                               at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:608)
                                                               at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3693)
                                                               at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3410)
                                                               at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3962)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.support.v4.widget.SwipeRefreshLayout.onLayout(SwipeRefreshLayout.java:610)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1080)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                               at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
                                                               at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
                                                               at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1172)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                               at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
                                                               at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
                                                               at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                               at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1791)
                                                               at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1635)
                                                               at android.widget.LinearLayout.onLayout(LinearLayout.java:1544)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
                                                               at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
31357-31357/com.myapp.app E/UncaughtException:     at com.android.internal.policy.DecorView.onLayout(DecorView.java:758)
                                                               at android.view.View.layout(View.java:19590)
                                                               at android.view.ViewGroup.layout(ViewGroup.java:6053)
                                                               at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2484)
                                                               at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2200)
                                                               at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
                                                               at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
                                                               at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
                                                               at android.view.Choreographer.doCallbacks(Choreographer.java:723)
                                                               at android.view.Choreographer.doFrame(Choreographer.java:658)
                                                               at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
                                                               at android.os.Handler.handleCallback(Handler.java:789)
                                                               at android.os.Handler.dispatchMessage(Handler.java:98)
                                                               at android.os.Looper.loop(Looper.java:164)
                                                               at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                               at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

If I remove groupAdapter.add(new MyItem()); then it runs, but it doesn't populate my recyclerView with anything which makes sense, but figured I'd throw it in.

Update: I'm now using 2.0.0 instead of alpha 2 (since #139 was resolved), but I'm still getting the same issue.

I was able to reproduce this and have a pretty good idea what's going on. Will try to fix over the weekend. Sorry for delay!

Awesome! Ability to repro is great news!

@lisawray I'm facing the same issue as @ColtonIdle .
I am getting the same error when adding the item.
java.lang.ClassCastException: com.xwray.groupie.ViewHolder cannot be cast to com.juster.feature.record.extcam.ExtCamMediaHeader$MediaItemViewHolder
Is there any workaround?

I solved my problem by referring to issue #128
Just override createViewHolder and make it return new instance of your own view holder, as said by @lisawray
You can find my sample implementation below. :)
```
package com.juster.feature.record.extcam;

import android.support.annotation.NonNull;
import android.view.View;
import android.widget.TextView;

import com.juster.R;
import com.xwray.groupie.Item;
import com.xwray.groupie.ViewHolder;

public class ExtCamMediaHeader extends Item {

private String mRoomName;
private int mMediaCount;


public ExtCamMediaHeader(String roomName, int mediaCount) {
    this.mRoomName = roomName;
    this.mMediaCount = mediaCount;
}

@NonNull
@Override
public MediaItemViewHolder createViewHolder(@NonNull View itemView) {
    return new MediaItemViewHolder(itemView);
}

@Override
public void bind(@NonNull MediaItemViewHolder viewHolder, int position) {
    viewHolder.tv_roomName.setText(mRoomName);
    viewHolder.tv_mediaCount.setText(String.valueOf(mMediaCount));
}

@Override
public int getLayout() {
    return R.layout.ext_cam_header;
}

class MediaItemViewHolder extends ViewHolder {

    TextView tv_roomName, tv_mediaCount;

    MediaItemViewHolder(View view) {
        super(view);
        tv_roomName = view.findViewById(R.id.tv_roomName);
        tv_mediaCount = view.findViewById(R.id.tv_mediaCount);
    }
}

}
````

Thank you so much @aayushthakur . It's unbelievable that I solved this problem and have now forgotten (twice) that I did so.

I will make a point to update the README to explain. It's not difficult but it's definitely not intuitive!

I updated the README to explicitly include a section on legacy viewholders. If you think it could be more clear PRs welcome :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FabianTerhorst picture FabianTerhorst  路  6Comments

ValCanBuild picture ValCanBuild  路  6Comments

amervelic picture amervelic  路  3Comments

ValCanBuild picture ValCanBuild  路  5Comments

kawaiiDango picture kawaiiDango  路  5Comments