RecyclerView实现多种item布局-----学习

Posted zhangtian6691844

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RecyclerView实现多种item布局-----学习相关的知识,希望对你有一定的参考价值。

RecyclerView实现多种item布局


在项目中列表是基本都会用到的,然而在显示列表时,我们需要的数据可能需要不止一种item显示,对于复杂的数据就需要多种item,以不同的样式显示出来,这样效果是很棒的,我们先看一下效果


我们可以看到,这个RecyclerView中有多种item显示出来,那么具体怎么实现呢,其实在RecyclerView中,我们可以重写方法getItemViewType(),这个方法会传进一个参数position表示当前是第几个Item,然后我们可以通过position拿到当前的Item对象,然后判断这个item对象需要那种视图,返回一个int类型的视图标志,然后在onCreatViewHolder方法中给引入布局,这样就能够实现多种item显示了,讲了这么多我们看一下具体的例子

[java] view plain copy
  1. @Override  
  2. public int getItemViewType(int position)   
  3.     if(list.size() == 0)  
  4.         return EMPTY_VIEW;  
  5.      else if(list.get(position) == null)  
  6.         return PROGRESS_VIEW;  
  7.      else if(list.get(position).getType().equals(News.IMAGE_NEWS))  
  8.         return IMAGE_VIEW;  
  9.      else   
  10.         return super.getItemViewType(position);  
  11.       
  12.   
首先我们重写了getItemViewType这个方法,在这个方法中根据position对item对象做了一些判断,如果存储item对象的集合大小为空,返回空view标识(这里为1),如果item对象为null,返回进度条标识,这个主要是用于实现下拉加载更多,如果item对象类型属于图片类型,就返回图片类型对应的Item,这个就是效果图中的第一个Item类型,否则就是其它类型,也就是效果图中的另一种item布局,然后我们在onCreatViewHolder中具体的为每一种类型引入其布局

[java] view plain copy
  1. @Override  
  2. public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)   
  3.     View view;  
  4.     if(viewType == PROGRESS_VIEW)  
  5.         view = LayoutInflater.from(parent.getContext()).inflate(R.layout.progressbar_item, parent, false);  
  6.         return new ProgressViewHolder(view);  
  7.      else if(viewType == EMPTY_VIEW)  
  8.         return null;  
  9.      else if(viewType == IMAGE_VIEW)  
  10.         view = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_news_item, parent, false);  
  11.         return new ImageViewHolder(view);  
  12.      else   
  13.         view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, false);  
  14.         return new NewsViewHolder(view);  
  15.       
  16.   
上面的代码就是具体为每种viewType引入其对应的布局,这样就基本实现了多种item布局,但是仅仅是这些还不够,因为我们还要对每种item设置数据,所以还要对每种item写一个VIewHolder来为item显示数据

[java] view plain copy
  1. class NewsViewHolder extends RecyclerView.ViewHolder  
  2.   
  3.     @BindView(R.id.news_title)TextView title;  
  4.     @BindView(R.id.news_digest)TextView digest;  
  5.     @BindView(R.id.news_time)TextView time;  
  6.     @BindView(R.id.news_src)ImageView image;  
  7.   
  8.     public NewsViewHolder(View itemView)   
  9.         super(itemView);  
  10.         ButterKnife.bind(this, itemView);  
  11.       
  12.   
  13.   
  14. class ImageViewHolder extends RecyclerView.ViewHolder  
  15.   
  16.     @BindView(R.id.news_title) TextView title;  
  17.     @BindView(R.id.image_left) ImageView imageLeft;  
  18.     @BindView(R.id.image_right) ImageView imageRight;  
  19.     @BindView(R.id.image_middle) ImageView imageMiddle;  
  20.     @BindView(R.id.news_time) TextView time;  
  21.   
  22.     public ImageViewHolder(View itemView)   
  23.         super(itemView);  
  24.         ButterKnife.bind(this, itemView);  
  25.       
  26.   
  27.   
  28. class ProgressViewHolder extends RecyclerView.ViewHolder   
  29.   
  30.     @BindView(R.id.progressBar) ProgressBar progressBar;  
  31.     @BindView(R.id.textView) TextView textView;  
  32.   
  33.     public ProgressViewHolder(View itemView)   
  34.         super(itemView);  
  35.         ButterKnife.bind(this, itemView);  
  36.       
  37.   
上面就是item对应的几个ViewHolder,判断viewHolder属于那种对象,然后在onBindViewHolder中根据对应的ViewHolder对其控件设置数据并显示

[java] view plain copy
  1. @Override  
  2. public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position)   
  3.     holder.itemView.setOnClickListener(new View.OnClickListener()   
  4.         @Override  
  5.         public void onClick(View v)   
  6.             clickListener.onItemClick(v, position);  
  7.           
  8.     );  
  9.     if(holder instanceof NewsViewHolder)  
  10.         NewsViewHolder viewHolder = (NewsViewHolder)holder;  
  11.         viewHolder.title.setText(list.get(position).getTitle());  
  12.         viewHolder.time.setText(list.get(position).getTime());  
  13.         /** 
  14.          * Glide加载图片 
  15.          */  
  16.         Glide.with(context).load(list.get(position).getImageUrl().get(0))  
  17.                 .override(dpToPx(72), dpToPx(72)).centerCrop().into(viewHolder.image);  
  18.         if(list.get(position).getType().equals(News.TEXT_NEWS))  
  19.             viewHolder.digest.setText(list.get(position).getDigest());  
  20.          else   
  21.             viewHolder.digest.setText("");  
  22.           
  23.      else if(holder instanceof ImageViewHolder)  
  24.         ImageViewHolder viewHolder = (ImageViewHolder)holder;  
  25.         viewHolder.title.setText(list.get(position).getTitle());  
  26.         viewHolder.time.setText(list.get(position).getTime());  
  27.         setItemImage(viewHolder, list, position);  
  28.      else if(holder instanceof ProgressViewHolder)  
  29.         ProgressViewHolder viewHolder = (ProgressViewHolder)holder;  
  30.         viewHolder.progressBar.setIndeterminate(true);  
  31.   
  32.       
  33.   

整个过程基本就是这样,这种方式在项目中经常会用到,我们就可以这样去处理,下拉加载更多就可以这样实现,在加载完数据后再往对象集合中传入null,然后判断如果出现null就加载progressBar布局,再加上Google官方的SwipeRefreshLayout,下拉刷新,上拉加载就搞定了,其实很容易,而且也有点Material Design 的感觉~~~~~~

看下Adapter的全部代码

[java] view plain copy
  1. package com.zmt.e_read.Adapter;  
  2.   
  3. import android.content.Context;  
  4. import android.support.v7.widget.RecyclerView;  
  5. import android.util.DisplayMetrics;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.ImageView;  
  10. import android.widget.TextView;  
  11.   
  12. import com.bumptech.glide.Glide;  
  13. import com.zmt.e_read.Module.News;  
  14. import com.zmt.e_read.Module.OnItemClickListener;  
  15. import com.zmt.e_read.R;  
  16. import com.zmt.e_read.Utils.ProgressViewHolder;  
  17.   
  18. import java.util.Collection;  
  19. import java.util.Collections;  
  20. import java.util.List;  
  21.   
  22. import butterknife.BindView;  
  23. import butterknife.ButterKnife;  
  24.   
  25. /** 
  26.  * Created by Dangelo on 2016/9/27. 
  27.  */  
  28. public class NewsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>   
  29.   
  30.     private final int EMPTY_VIEW = 1;  
  31.     private final int PROGRESS_VIEW = 2;  
  32.     private final int IMAGE_VIEW = 3;  
  33.   
  34.     private Context context;  
  35.     private List<News> list;  
  36.     private OnItemClickListener clickListener;  
  37.   
  38.     public NewsAdapter(Context context, List<News> list, OnItemClickListener clickListener)   
  39.         this.context = context;  
  40.         this.list = list;  
  41.         this.clickListener = clickListener;  
  42.       
  43.   
  44.     public void addOnItemClickListener(OnItemClickListener clickListener)  
  45.         this.clickListener = clickListener;  
  46.       
  47.   
  48.     @Override  
  49.     public int getItemViewType(int position)   
  50.         if(list.size() == 0)  
  51.             return EMPTY_VIEW;  
  52.          else if(list.get(position) == null)  
  53.             return PROGRESS_VIEW;  
  54.          else if(list.get(position).getType().equals(News.IMAGE_NEWS))  
  55.             return IMAGE_VIEW;  
  56.          else   
  57.             return super.getItemViewType(position);  
  58.           
  59.       
  60.   
  61.     @Override  
  62.     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)   
  63.         View view;  
  64.         if(viewType == PROGRESS_VIEW)  
  65.             view = LayoutInflater.from(parent.getContext()).inflate(R.layout.progressbar_item, parent, false);  
  66.             return new ProgressViewHolder(view);  
  67.          else if(viewType == EMPTY_VIEW)  
  68.             return null;  
  69.          else if(viewType == IMAGE_VIEW)  
  70.             view = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_news_item, parent, false);  
  71.             return new ImageViewHolder(view);  
  72.          else   
  73.             view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, false);  
  74.             return new NewsViewHolder(view);  
  75.           
  76.       
  77.   
  78.     @Override  
  79.     public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position)   
  80.         holder.itemView.setOnClickListener(new View.OnClickListener()   
  81.             @Override  
  82.             public void onClick(View v)   
  83.                 clickListener.onItemClick(v, position);  
  84.               
  85.         );  
  86.         if(holder instanceof NewsViewHolder)  
  87.             NewsViewHolder viewHolder = (NewsViewHolder)holder;  
  88.             viewHolder.title.setText(list.get(position).getTitle());  
  89.             viewHolder.time.setText(list.get(position).getTime());  
  90.             /** 
  91.              * Glide加载图片 
  92.              */  
  93.             Glide.with(context).load(list.get(position).getImageUrl().get(0))  
  94.                     .override(dpToPx(72), dpToPx(72)).centerCrop().into(viewHolder.image);  
  95.             if(list.get(position).getType().equals(News.TEXT_NEWS))  
  96.                 viewHolder.digest.setText(list.get(position).getDigest());  
  97.              else   
  98.                 viewHolder.digest.setText("");  
  99.               
  100.          else if(holder instanceof ImageViewHolder)  
  101.             ImageViewHolder viewHolder = (ImageViewHolder)holder;  
  102.             viewHolder.title.setText(list.get(position).getTitle());  
  103.             viewHolder.time.setText(list.get(position).getTime());  
  104.             setItemImage(viewHolder, list, position);  
  105.          else if(holder instanceof ProgressViewHolder)  
  106.             ProgressViewHolder viewHolder = (ProgressViewHolder)holder;  
  107.             viewHolder.progressBar.setIndeterminate(true);  
  108.   
  109.           
  110.       
  111.   
  112.     public void setItemImage(ImageViewHolder viewHolder, List<News> list, int position)  
  113.         viewHolder.imageMiddle.setVisibility(View.VISIBLE);  
  114.         viewHolder.imageRight.setVisibility(View.VISIBLE);  
  115.         DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();  
  116.         if(list.get(position).getImageUrl().size() == 1)  
  117.             Glide.with(context).load(list.get(position).getImageUrl().get(0))  
  118.                     .override(displayMetrics.widthPixels - dpToPx(10), dpToPx(90))  
  119.                     .centerCrop().into(viewHolder.imageLeft);  
  120.             viewHolder.imageMiddle.setVisibility(View.GONE);  
  121.             viewHolder.imageRight.setVisibility(View.GONE);  
  122.          else if(list.get(position).getImageUrl().size() == 2)  
  123.             int imageWidth = (displayMetrics.widthPixels - dpToPx(20)) / 2;  
  124.             Glide.with(context).load(list.get(position).getImageUrl().get(0))  
  125.                     .override(imageWidth, dpToPx(90))  
  126.                     .centerCrop().into(viewHolder.imageLeft);  
  127.             Glide.with(context).load(list.get(position).getImageUrl().get(1))  
  128.                     .override(imageWidth, dpToPx(90))  
  129.                     .centerCrop().into(viewHolder.imageMiddle);  
  130.             viewHolder.imageRight.setVisibility(View.GONE);  
  131.          else if(list.get(position).getImageUrl().size() >= 3)  
  132.             int imageWidth = (displayMetrics.widthPixels - dpToPx(30)) / 3;  
  133.             Glide.with(context).load(list.get(position).getImageUrl().get(0))  
  134.                     .override(imageWidth, dpToPx(90))  
  135.                     .centerCrop().into(viewHolder.imageLeft);  
  136.             Glide.with(context).load(list.get(position).getImageUrl().get(1))  
  137.                     .override(imageWidth, dpToPx(90))  
  138.                     .centerCrop().into(viewHolder.imageMiddle);  
  139.             Glide.with(context).load(list.get(position).getImageUrl().get(2))  
  140.                     .override(imageWidth, dpToPx(90))  
  141.                     .centerCrop().into(viewHolder.imageRight);  
  142.           
  143.       
  144.   
  145.     @Override  
  146.     public int getItemCount()   
  147.         return list.size();  
  148.       
  149.   
  150.     public int dpToPx(float dp)  
  151.         float px = context.getResources().getDisplayMetrics().density;  
  152.         return (int)(dp * px + 0.5f);  
  153.       
  154.   
  155.     class NewsViewHolder extends RecyclerView.ViewHolder  
  156.   
  157.         @BindView(R.id.news_title)TextView title;  
  158.         @BindView(R.id.news_digest)TextView digest;  
  159.         @BindView(R.id.news_time)TextView time;  
  160.         @BindView(R.id.news_src)ImageView image;  
  161.   
  162.         public NewsViewHolder(View itemView)   
  163.             super(itemView);  
  164.             ButterKnife.bind(this, itemView);  
  165.           
  166.       
  167.   
  168.     class ImageViewHolder extends RecyclerView.ViewHolder  
  169.   
  170.         @BindView(R.id.news_title) TextView title;  
  171.         @BindView(R.id.image_left) ImageView imageLeft;  
  172.         @BindView(R.id.image_right) ImageView imageRight;  
  173.         @BindView(R.id.image_middle) ImageView imageMiddle;  
  174.         @BindView(R.id.news_time) TextView time;  
  175.   
  176.         public ImageViewHolder(View itemView)   
  177.             super(itemView);  
  178.             ButterKnife.bind(this, itemView);  
  179.           
  180.       
  181.           
  182.     <pre name="code" class="java">    class ProgressViewHolder extends RecyclerView.ViewHolder   
  183.   
  184.         @BindView(R.id.progressBar) ProgressBar progressBar;  
  185.         @BindView(R.id.textView) TextView textView;  
  186.   
  187.         public ProgressViewHolder(View itemView)   
  188.             super(itemView);  
  189.             ButterKnife.bind(this, itemView);  
  190.           
  191.       

项目地址:https://github.com/xiyouZmt/E-Read


转载    请标注原文出处。 https://blog.csdn.net/zhumintao/article/details/53023920

以上是关于RecyclerView实现多种item布局-----学习的主要内容,如果未能解决你的问题,请参考以下文章

如何彻底更改 recyclerview 中的 item 布局中的某个控件的某个属性

Adapter的封装之路

Recyclerview实现展开、折叠分组,多种布局,多种divider

android RecyclerView GridLayoutManager 多布局(每个Item带标题)

为RecyclerView的不同item项实现不同的布局(添加分类Header)

RecyclerView添加多个样式不同的Item布局