I have a layout with recyclerview
.
In this recyclerview
I have 2 types of layouts: regular + loading.
This recyclerview
shows a grid of 3x3 items and for every 5 items I do pagination for the next 5. while doing pagination, each 5th item shows loading until that data was received.
However, In the last batch, it loads the last items and it keeps the loading view as the last item.
In order to overcome this, I have to reload the whole recyclerview
which seems wrong to me.
How can I update the view type of the last item when it is the last batch?
My code looks as follows:
public class MoreItemsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<DiscoverItems> discoverItems;
private FirebaseFirestore db;
private FirebaseAuth auth;
private boolean isLoadingFlag;
interface OnDiscoverItemClickListener {
void onClick(DiscoverItems discoverItems);
}
private OnDiscoverItemClickListener listener;
public MoreItemsAdapter(List<DiscoverItems> discoverItems, Boolean isLoadingFlag, OnDiscoverItemClickListener listener) {
this.discoverItems = discoverItems;
this.isLoadingFlag = isLoadingFlag;
this.listener = listener;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
if (viewType == AppConstants.ITEMS_LOADING_KEY) {
view = LayoutInflater.from( parent.getContext() ).inflate(
R.layout.item_loading_items, parent, false );
return new LoadingViewHolder( view );
} else {
view = LayoutInflater.from( parent.getContext() ).inflate(
R.layout.item_item_more,
parent,
false );
return new MoreItemsViewHolder( view );
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
viewHolder.setIsRecyclable( false );
if (viewHolder instanceof MoreItemsViewHolder) {
((MoreItemsViewHolder) viewHolder).bind( (discoverItems.get( position )) );
} else if (viewHolder instanceof LoadingViewHolder) {
showLoadingView( (LoadingViewHolder) viewHolder, position );
}
}
@Override
public int getItemViewType(int position) {
if (position == discoverItems.size() - 1 && discoverItems.size() > AppConstants.LOAD_MORE_MORE && isLoadingFlag) {
return AppConstants.ITEMS_LOADING_KEY;
} else {
return AppConstants.ITEMS_REGULAR_KEY;
}
}
@Override
public int getItemCount() {
return discoverItems.size();
}
class MoreItemsViewHolder extends RecyclerView.ViewHolder {
Button tv_Link;
CardView cardView;
private MoreItemsViewHolder(View itemView) {
super( itemView );
cardView = itemView.findViewById( R.id.imagecard );
tv_Link = itemView.findViewById( R.id.tv_Link );
}
private void bind(DiscoverItems discoverItems) {
this.discoverItems = discoverItems;
DO SOMETHING
}
}
private static class LoadingViewHolder extends RecyclerView.ViewHolder {
ProgressBar progressBar;
public LoadingViewHolder(@NonNull View itemView) {
super( itemView );
progressBar = itemView.findViewById( R.id.progressBar );
}
}
private void showLoadingView(MoreItemsAdapter.LoadingViewHolder viewHolder, int position) {
}
}
In my code outside of the adapter, I did the following for the last batch (set the second parameter to false to make it understand that it is regular view):
rv_More.invalidate();
rv_More.scrollToPosition( items.size() - loadingNumber - 1 );
moreItemsAdapter = new MoreItemsAdapter( items, false, listener );
rv_More.getItemAnimator().setChangeDuration( 0 );
rv_More.setAdapter( moreItemsAdapter );
isLoading = true;
Cant I do instead something like:
rv_More.setViewType(position, Type)
Thank you