Thomas D'haen
Thomas D'haen

Reputation: 9

multple viewholder recyclerview not loading off screen views

Im creating a Recyclerview and have 3 different ViewHolders. My adapter class looks like this:

public class ProfileAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private List<Object> items = new ArrayList<>();
private Context context;

public ProfileAdapter(Context context, List<Object> items) {
    this.context = context;
    this.items = items;
}



@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = null;
    RecyclerView.ViewHolder viewHolder = null;
    int listViewItemType = getItemViewType(viewType);
    switch (listViewItemType) {
        case 0:
            view = LayoutInflater.from(context).inflate(R.layout.fragment_profile_user, parent, false);
            return new ProfileMainItemViewHolder(context,view);
        case 1:
            view = LayoutInflater.from(context).inflate(R.layout.view_search_playlist_item, parent, false);
            return new PlaylistItemViewHolder(context,view);
        case 2:
            view = LayoutInflater.from(context).inflate(R.layout.card_item_home_new, parent, false);
            return new EventItemViewHolder(context, view);
        default:
            viewHolder = null;
    }
    return viewHolder;
}



@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    switch (holder.getItemViewType()) {
        case 0:
            ((ProfileMainItemViewHolder) holder).render((User) items.get(position));
            break;
        case 1:
            ((PlaylistItemViewHolder) holder).render(context, (Playlist) items.get(position), "");
            break;
        case 2:
            ((EventItemViewHolder) holder).render((Event) items.get(position));
            break;
    }
}

public void updateItems(List<Object> items){
    this.items = sortItemList(items);
    notifyDataSetChanged();
}

@Override
public int getItemViewType(int position) {
    if(items.get(position) instanceof User){
        return 0;
    } else if (items.get(position) instanceof Playlist){
        return 1;
    } else if (items.get(position) instanceof Event){
        return 2;
    }
    return -1;
}

private List<Object> sortItemList(List<Object> list){
    ArrayList<Object> sortedList = new ArrayList<>();
    //Add User object first
    for (Object o : list) {
        if(o instanceof User){
            sortedList.add(o);
        }
    }
    //Then Playlist objects
    for (Object o : list) {
        if(o instanceof Playlist){
            sortedList.add(o);
        }
    }
    //Then Events
    for (Object o : list) {
        if(o instanceof Event){
            sortedList.add(o);
        }
    }
    return sortedList;
}

@Override
public int getItemCount() {
    return this.items.size();
}

}

It loads all visible items perfectly, however when I scroll down and an object of an instance is loaded that was not visible on top, the app gives an error:

AndroidRuntime: java.lang.ClassCastException: com.surfsup.viewholder.PlaylistItemViewHolder cannot be cast to com.surfsup.viewholder.EventItemViewHolder AndroidRuntime: at com.surfsup.adapters.ProfileAdapter.onBindViewHolder(ProfileAdapter.java:76) AndroidRuntime: at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5138) AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4433) AndroidRuntime: at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4326)

Am I overseeing something? Thanks

Upvotes: 1

Views: 1184

Answers (1)

mixel
mixel

Reputation: 25866

You do not have to call getItemViewType(viewType) to get view type. viewType parameter is already view type value evaluated by RecyclerView.Adapter from overrided getItemViewType() method and passed in onCreateViewHolder() method.

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = null;
    RecyclerView.ViewHolder viewHolder = null;
    switch (viewType) {
        case 0:
            view = LayoutInflater.from(context).inflate(R.layout.fragment_profile_user, parent, false);
            return new ProfileMainItemViewHolder(context,view);
        case 1:
            view = LayoutInflater.from(context).inflate(R.layout.view_search_playlist_item, parent, false);
            return new PlaylistItemViewHolder(context,view);
        case 2:
            view = LayoutInflater.from(context).inflate(R.layout.card_item_home_new, parent, false);
            return new EventItemViewHolder(context, view);
        default:
            viewHolder = null;
    }
    return viewHolder;
}

Upvotes: 1

Related Questions