title: Change RecyclerView.ViewHolder Layout from outside Adapter
body: <p>I have a layout with <code>recyclerview</code>.</p>
  <p>In this <code>recyclerview</code> I have 2 types of layouts: regular + loading.</p>
  <p>This <code>recyclerview</code> 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.</p>
  <p>However, In the last batch, it loads the last items and it keeps the loading view as the last item.</p>
  <p><a href="https://i.stack.imgur.com/p1nFO.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/p1nFO.png" alt="" /></a></p>
  <p>In order to overcome this, I have to reload the whole <code>recyclerview</code> which seems wrong to me.</p>
  <p>How can I update the view type of the last item when it is the last batch?</p>
  <p>My code looks as follows:</p>
  <pre><code>public class MoreItemsAdapter extends RecyclerView.Adapter&lt;RecyclerView.ViewHolder&gt; {
  
      private List&lt;DiscoverItems&gt; discoverItems;
      private FirebaseFirestore db;
      private FirebaseAuth auth;
  
      private boolean isLoadingFlag;
  
      interface OnDiscoverItemClickListener {
          void onClick(DiscoverItems discoverItems);
      }
  
      private OnDiscoverItemClickListener listener;
  
      public MoreItemsAdapter(List&lt;DiscoverItems&gt; 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 &amp;&amp; discoverItems.size() &gt; AppConstants.LOAD_MORE_MORE &amp;&amp; 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) {
      }
  
  
  }
  </code></pre>
  <p>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):</p>
  <pre><code>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;
  </code></pre>
  <p>Cant I do instead something like:</p>
  <pre><code>rv_More.setViewType(position, Type)
  </code></pre>
  <p>Thank you</p>