6rchid
6rchid

Reputation: 1301

getItemViewType is returned only in onBindViewHolder but not in onCreateViewHolder

I have a RecyclerView adapter that should inflate 4 different layouts depending on what getItemViewType returns.

Each view type should be returned when the view is triggered, but the problem is one of the types does not return inside the onCreateViewHolder, but returns only in onBindViewHolder, thus preventing the ViewHolder from being created. Also I assure you getItemCount returns just the correct size of the data, so that should not be the problem.

I figure if the view types can be returned successfully they should show up in both methods when called. So this issue just doesn't make any sense to me.

@NonNull
@Override
public HorizontalViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
    Log.d(SLIDER_TAG, "onCreateViewHolder: " + getItemViewType(i));
    View cardView = LayoutInflater.from(parent.getContext()).inflate(
                    getItemViewType(i) == 0 ? R.layout.item_category_slider_viewed
                    : getItemViewType(i) == 1 ? R.layout.item_category_slider_added
                    : getItemViewType(i) == 2 ? R.layout.item_category_slider_browse_all
                    : R.layout.item_category_slider_regular
            , parent, false);
    return new HorizontalViewHolder(cardView, context);
}

When logging the getItemViewType(i) only 0, 1, and 3 are ever returned inside the onCreateViewHolder but not 2.

But strangely, logging that inside the onBindViewHolder returns all the view types from 0 - 3. Why is that the case?


EDIT

The RecyclerView displays a horizontal list of cards (about 20) while all but the last card (blank) uses the same layout, so only 2 view types are used in this specific list case, we can ignore the other 2 types for now. Here the last card is not inflated, thus was never called in the onCreateViewHolder. I'm suspecting that while the first many cards were inflated using the same layout, the layouts are not created again so it assumes that the last card uses the same layout.

Upvotes: 0

Views: 251

Answers (1)

ישו אוהב אותך
ישו אוהב אותך

Reputation: 29794

The problem probably because you're rechecking for the itemViewType with getItemViewType(i)); inside of onCreateViewHolder. You shouldn't do that because onCreateViewHolder already giving you the itemViewType from its parameters. And you should use a switch case instead of if ? : to make your code more readable.

So, change your code to something like this:

@Override
public HorizontalViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    int layoutId;
    switch(viewType) {
       case 0:
         layoutId = R.layout.item_category_slider_viewed;
       break;
       case 1:
         layoutId = R.layout.item_category_slider_added;
       break;
       case 2:
         layoutId = R.layout.item_category_slider_browse_all;
       break;
       default:
         layoutId = R.layout.item_category_slider_regular;

    }

    View cardView = LayoutInflater.from(parent.getContext()).inflate(
                    layoutId, parent, false);

    return new HorizontalViewHolder(cardView, context);
}

Upvotes: 1

Related Questions