title: Multiple row layouts using RecyclerView
body: <p>According <a href="http://blog.iamsuleiman.com/android-pagination-recyclerview-tutorial-api-retrofit-gson/" rel="nofollow noreferrer">this tutorial</a>,  I could publish json content <strong>(result array)</strong> on RecyclerView in one screen.</p>
  
  <p>Now, I changed json file to this:</p>
  
  <pre><code> "page": 1, 
      "results": [ { ... } ],
      "menus": [ { ... } ]
  }, "total_results": 5450, "total_pages": 273 }
  </code></pre>
  
  <p>Now I want import <strong>menus array</strong> to the RecyclerView  on same screen.(at first rows).
  And after that import <strong>result array</strong>.</p>
  
  <p><strong>menus array</strong> has not pagination.</p>
  
  <p>I created model class for menu (<strong>LastMedicMenu.java</strong>).</p>
  
  <p>I am noob. So now, I think I must change adapter.</p>
  
  <p>Original adapter is:</p>
  
  <p><strong>orginal adapter:</strong></p>
  
  <pre><code>public class MedicPaginationAdapter extends RecyclerView.Adapter&lt;RecyclerView.ViewHolder&gt; {
  
      private static final int ITEM = 0;
      private static final int LOADING = 1;
      private static final String BASE_URL_IMG = "http://www.example.com/api/service/img";
  
      private List&lt;LastMedicResult&gt; medicResults;
      private Context context;
  
      private boolean isLoadingAdded = false;
  
      public MedicPaginationAdapter(Context context) {
          this.context = context;
          medicResults = new ArrayList&lt;&gt;();
      }
  
      public List&lt;LastMedicResult&gt; getMedics() {
          return medicResults;
      }
  
  
      public void setMedics(List&lt;LastMedicResult&gt; medicResults) {
          this.medicResults = medicResults;
      }
  
      @Override
      public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          RecyclerView.ViewHolder viewHolder = null;
          LayoutInflater inflater = LayoutInflater.from(parent.getContext());
  
          switch (viewType) {
              case ITEM:
                  viewHolder = getViewHolder(parent, inflater);
                  break;
              case LOADING:
                  View v2 = inflater.inflate(R.layout.item_progress, parent, false);
                  viewHolder = new LoadingVH(v2);
                  break;
          }
          return viewHolder;
      }
  
      @NonNull
      private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
          RecyclerView.ViewHolder viewHolder;
          View v1 = inflater.inflate(R.layout.service_list, parent, false);
          viewHolder = new MedicVH(v1);
          return viewHolder;
      }
  
      @Override
      public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
  
          LastMedicResult result = medicResults.get(position); // Movie
  
          switch (getItemViewType(position)) {
              case ITEM:
                  final MedicVH MedicVH = (MedicVH) holder;
  
                  MedicVH.mMovieTitle.setText(result.getTitle());
  
  
  
                  MedicVH.sLocation.setText(result.getServiceLocation());
                  MedicVH.sType.setText(result.getServiceType());
                  MedicVH.mMovieDesc.setText(result.getOverview());
  
  
                  Glide
                          .with(context)
                          .load(BASE_URL_IMG + result.getPosterPath())
                          .listener(new RequestListener&lt;String, GlideDrawable&gt;() {
                              @Override
                              public boolean onException(Exception e, String model, Target&lt;GlideDrawable&gt; target, boolean isFirstResource) {
                                  // TODO: 08/11/16 handle failure
                                  MedicVH.mProgress.setVisibility(View.GONE);
                                  return false;
                              }
  
                              @Override
                              public boolean onResourceReady(GlideDrawable resource, String model, Target&lt;GlideDrawable&gt; target, boolean isFromMemoryCache, boolean isFirstResource) {
                                  // image ready, hide progress now
                                  MedicVH.mProgress.setVisibility(View.GONE);
                                  return false;   // return false if you want Glide to handle everything else.
                              }
                          })
                          .diskCacheStrategy(DiskCacheStrategy.ALL)   // cache both original &amp; resized image
                          .centerCrop()
                          .crossFade()
                          .into(MedicVH.mPosterImg);
  
  
  
                  break;
  
              case LOADING:
  //                Do nothing
                  break;
          }
  
      }
  
      @Override
      public int getItemCount() {
          return medicResults == null ? 0 : medicResults.size();
      }
  
      @Override
      public int getItemViewType(int position) {
          return (position == medicResults.size() - 1 &amp;&amp; isLoadingAdded) ? LOADING : ITEM;
      }
  
  
      /*
     Helpers
      */
  
      public void add(LastMedicResult r) {
          medicResults.add(r);
          notifyItemInserted(medicResults.size() - 1);
      }
  
      public void addAll(List&lt;LastMedicResult&gt; moveResults) {
          for (LastMedicResult result : moveResults) {
              add(result);
          }
      }
  
      public void remove(LastMedicResult r) {
          int position = medicResults.indexOf(r);
          if (position &gt; -1) {
              medicResults.remove(position);
              notifyItemRemoved(position);
          }
      }
  
      public void clear() {
          isLoadingAdded = false;
          while (getItemCount() &gt; 0) {
              remove(getItem(0));
          }
      }
  
      public boolean isEmpty() {
          return getItemCount() == 0;
      }
  
  
      public void addLoadingFooter() {
          isLoadingAdded = true;
          add(new LastMedicResult());
      }
  
      public void removeLoadingFooter() {
          isLoadingAdded = false;
  
          int position = medicResults.size() - 1;
          LastMedicResult result = getItem(position);
  
          if (result != null) {
              medicResults.remove(position);
              notifyItemRemoved(position);
          }
      }
  
      public LastMedicResult getItem(int position) {
          return medicResults.get(position);
      }
  
  
      protected class MedicVH extends RecyclerView.ViewHolder {
          private TextView mMovieTitle;
          private TextView mMovieDesc;
          private TextView sLocation;
          private TextView sType;
          private ImageView mPosterImg;
          private ProgressBar mProgress;
  
          public MedicVH(View itemView) {
              super(itemView);
  
              mMovieTitle = (TextView) itemView.findViewById(R.id.movie_title);
  
  
              mMovieDesc = (TextView) itemView.findViewById(R.id.movie_desc);
  
  
  
              sLocation = (TextView) itemView.findViewById(R.id.service_location);
  
  
              sType = (TextView) itemView.findViewById(R.id.service_type);
  
  
              mPosterImg = (ImageView) itemView.findViewById(R.id.movie_poster);
              mProgress = (ProgressBar) itemView.findViewById(R.id.movie_progress);
  
          }
      }
  
  
      protected class LoadingVH extends RecyclerView.ViewHolder {
  
          public LoadingVH(View itemView) {
              super(itemView);
          }
      }
  
  
  }
  </code></pre>
  
  <p>Please check my steps to change:</p>
  
  <p>1- 
  original code:</p>
  
  <pre><code>private static final int ITEM = 0; // for search
  private static final int LOADING = 1;// for progress bar
  </code></pre>
  
  <p>changed code:</p>
  
  <pre><code>private static final int ITEM = 0; // for search
  private static final int MENU = 1; // for search1
  private static final int LOADING = 2;// for progress bar
  </code></pre>
  
  <p>2-</p>
  
  <pre><code>public MedicPaginationAdapter(Context context) {
          this.context = context;
          medicResults = new ArrayList&lt;&gt;();
      }
  </code></pre>
  
  <p>to</p>
  
  <pre><code>public MedicPaginationAdapter(Context context) {
      this.context = context;
      medicResults = new ArrayList&lt;&gt;();
      medicMenus = new ArrayList&lt;&gt;();
  }
  </code></pre>
  
  <p>step 3:</p>
  
  <pre><code>public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          RecyclerView.ViewHolder viewHolder = null;
          LayoutInflater inflater = LayoutInflater.from(parent.getContext());
  
          switch (viewType) {
              case ITEM:
                  viewHolder = getViewHolder(parent, inflater);
                  break;
              case LOADING:
                  View v2 = inflater.inflate(R.layout.item_progress, parent, false);
                  viewHolder = new LoadingVH(v2);
                  break;
          }
          return viewHolder;
      }
  </code></pre>
  
  <p>to </p>
  
  <pre><code>@Override
      public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          RecyclerView.ViewHolder viewHolder = null;
          LayoutInflater inflater = LayoutInflater.from(parent.getContext());
  
          switch (viewType) {
              case ITEM:
                  viewHolder = getViewHolder(parent, inflater,viewType);
                  break;
              case MENU:
              viewHolder = getViewHolder(parent, inflater,viewType);
                  break;
              case LOADING:
                  View v2 = inflater.inflate(R.layout.item_progress, parent, false);
                  viewHolder = new LoadingVH(v2);
                  break;
          }
          return viewHolder;
      }
  </code></pre>
  
  <p>step 4:</p>
  
  <pre><code>private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater) {
          RecyclerView.ViewHolder viewHolder;
          View v1 = inflater.inflate(R.layout.service_list, parent, false);
          viewHolder = new MedicVH(v1);
          return viewHolder;
      }
  </code></pre>
  
  <p>to </p>
  
  <pre><code>private RecyclerView.ViewHolder getViewHolder(ViewGroup parent, LayoutInflater inflater, int viewType) {
          RecyclerView.ViewHolder viewHolder;
          View v1;
          if(ITEM == viewType)
          {
              v1 = inflater.inflate(R.layout.service_list, parent, false);
              viewHolder = new MedicVH(v1);
          }
          else
          {
              v1 = inflater.inflate(R.layout.service_munu_list, parent, false);
              viewHolder = new MedicMenuVH(v1);
          }
          return viewHolder;
      }
  </code></pre>
  
  <p>step 5:</p>
  
  <pre><code>public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
  
          LastMedicResult result = medicResults.get(position); 
  
  
          switch (getItemViewType(position)) {
              case ITEM:
                  final MedicVH MedicVH = (MedicVH) holder;
  
                  MedicVH.mMovieTitle.setText(result.getTitle());
                  ...
  
  
                  break;
  
              case LOADING:
                     //Do nothing
                  break;
          }
  
      }
  </code></pre>
  
  <p>to</p>
  
  <p>public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {</p>
  
  <pre><code>    LastMedicResult result = medicResults.get(position); 
      LastMedicResult menu = medicMenus.get(position); 
      switch (getItemViewType(position)) {
          case ITEM:
              final MedicVH MedicVH = (MedicVH) holder;
  
              MedicVH.mMovieTitle.setText(result.getTitle());
              ...
  
  
              break;
          case MENU:
              final MedicMenuVH MedicMenuVH = (MedicMenuVH) holder;
  
              MedicMenuVH .mMenuTitle.setText(menu.getTitle());
              ...
  
  
              break;
  
  
          case LOADING:
                 //Do nothing
              break;
      }
  
  }
  </code></pre>
  
  <p>step6:</p>
  
  <pre><code>@Override
      public int getItemViewType(int position) {
          return (position == medicResults.size() - 1 &amp;&amp; isLoadingAdded) ? LOADING : ITEM;
      }
  </code></pre>
  
  <p>to</p>
  
  <pre><code>public int getItemViewType(int position) {
          //return (position == medicResults.size() - 1 &amp;&amp; isLoadingAdded) ? ITEM : ITEM;
          if(medicResults.get(position) instanceof LastMedicResult)
          {
              return (position == medicResults.size() - 1 &amp;&amp; isLoadingAdded) ? LOADING : ITEM;
          }
          else if(medicMenus.get(position) instanceof LastMedicMenu)
          {
              return (position == medicMenus.size() - 1 &amp;&amp; isLoadingAdded) ? LOADING : MENU;
          }
          else
          {
              return LOADING;
          }
      }
  </code></pre>
  
  <p>step 7:
  AND Finally add this class:</p>
  
  <pre><code>protected class MedicMenuVH extends RecyclerView.ViewHolder {
          private TextView mMenuTitle;
  
  
          public MedicMenuVH(View itemView) {
              super(itemView);
  
              mMenuTitle = (TextView) itemView.findViewById(R.id.menu_title);
  
          }
      }
  </code></pre>
  
  <p>After all change, It could only shows <strong>result array</strong> in RecyclerView.</p>
  
  <p>what is my wrong in the codes? can please tell me what should I to do else? </p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Accrording to answers I changed step 5 to this:</p>
  
  <pre><code>@Override
      public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
  
          LastMedicResult result = medicResults.get(position); // result
          LastMedicMenu menu = medicMenus.get(position);
  
          switch (getItemViewType(position)) {
              case ITEM:
                  final MedicVH MedicVH = (MedicVH) holder;
  
                  MedicVH.mMovieTitle.setText(result.getTitle());
  
                  break;
              case MENU:
              {
                  final MedicMenuVH MedicMenuVH = (MedicMenuVH) holder;
  
                  MedicMenuVH.mMenuTitle.setText(menu.getTitle());
                  break;
              }
              case LOADING:
                  //  Do nothing
                  break;
          }
  
      }
  </code></pre>
  
  <p>But I get an error (the app will be crash)  in error log for this line:</p>
  
  <pre><code>LastMedicMenu menu = medicMenus.get(position);
  </code></pre>
  
  <p>I created model class for menu before. </p>
  
  <p>why I get that error?</p>
  
  <blockquote>
    <p>04-08 14:34:55.954 15584-15584/com.example.teb E/AndroidRuntime: FATAL
    EXCEPTION: main
                                                                    java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
                                                                        at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
                                                                        at java.util.ArrayList.get(ArrayList.java:304)
                                                                        at com.example.teb.MedicPaginationAdapter.onBindViewHolder(MedicPaginationAdapter.java:105)</p>
  </blockquote>