Reputation: 9
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
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