Android RecyclerView实现多种item布局的方法

Android RecyclerView实现多种item布局的方法,第1张

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

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

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

@OverrIDe public int getItemVIEwType(int position) {   if(List.size() == 0){     return EMPTY_VIEW;   } else if(List.get(position) == null){     return PROGRESS_VIEW;   } else if(List.get(position).getType().equals(News.IMAGE_NEWS)){     return IMAGE_VIEW;   } else {     return super.getItemVIEwType(position);   } } 

首先我们重写了getItemVIEwType这个方法,在这个方法中根据position对item对象做了一些判断,如果存储item对象的集合大小为空,返回空vIEw标识(这里为1),如果item对象为null,返回进度条标识,这个主要是用于实现下拉加载更多,如果item对象类型属于图片类型,就返回图片类型对应的Item,这个就是效果图中的第一个Item类型,否则就是其它类型,也就是效果图中的另一种item布局,然后我们在onCreatVIEwHolder中具体的为每一种类型引入其布局

@OverrIDe public RecyclerVIEw.VIEwHolder onCreateVIEwHolder(VIEwGroup parent,int vIEwType) {   VIEw vIEw;   if(vIEwType == PROGRESS_VIEW){     vIEw = LayoutInflater.from(parent.getContext()).inflate(R.layout.progressbar_item,parent,false);     return new ProgressVIEwHolder(vIEw);   } else if(vIEwType == EMPTY_VIEW){     return null;   } else if(vIEwType == IMAGE_VIEW){     vIEw = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_news_item,false);     return new ImageVIEwHolder(vIEw);   } else {     vIEw = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item,false);     return new NewsVIEwHolder(vIEw);   } } 

上面的代码就是具体为每种vIEwType引入其对应的布局,这样就基本实现了多种item布局,但是仅仅是这些还不够,因为我们还要对每种item设置数据,所以还要对每种item写一个VIEwHolder来为item显示数据

class NewsVIEwHolder extends RecyclerVIEw.VIEwHolder{    @BindVIEw(R.ID.news_Title)TextVIEw Title;   @BindVIEw(R.ID.news_digest)TextVIEw digest;   @BindVIEw(R.ID.news_time)TextVIEw time;   @BindVIEw(R.ID.news_src)ImageVIEw image;    public NewsVIEwHolder(VIEw itemVIEw) {     super(itemVIEw);     ButterKnife.bind(this,itemVIEw);   } }  class ImageVIEwHolder extends RecyclerVIEw.VIEwHolder{    @BindVIEw(R.ID.news_Title) TextVIEw Title;   @BindVIEw(R.ID.image_left) ImageVIEw imageleft;   @BindVIEw(R.ID.image_right) ImageVIEw imageRight;   @BindVIEw(R.ID.image_mIDdle) ImageVIEw imageMIDdle;   @BindVIEw(R.ID.news_time) TextVIEw time;    public ImageVIEwHolder(VIEw itemVIEw) {     super(itemVIEw);     ButterKnife.bind(this,itemVIEw);   } }  class ProgressVIEwHolder extends RecyclerVIEw.VIEwHolder {    @BindVIEw(R.ID.progressbar) Progressbar progressbar;   @BindVIEw(R.ID.textVIEw) TextVIEw textVIEw;    public ProgressVIEwHolder(VIEw itemVIEw) {     super(itemVIEw);     ButterKnife.bind(this,itemVIEw);   } } 

上面就是item对应的几个VIEwHolder,判断vIEwHolder属于那种对象,然后在onBindVIEwHolder中根据对应的VIEwHolder对其控件设置数据并显示

@OverrIDe public voID onBindVIEwHolder(RecyclerVIEw.VIEwHolder holder,final int position) {   holder.itemVIEw.setonClickListener(new VIEw.OnClickListener() {     @OverrIDe     public voID onClick(VIEw v) {       clickListener.onItemClick(v,position);     }   });   if(holder instanceof NewsVIEwHolder){     NewsVIEwHolder vIEwHolder = (NewsVIEwHolder)holder;     vIEwHolder.Title.setText(List.get(position).getTitle());     vIEwHolder.time.setText(List.get(position).getTime());     /**      * GlIDe加载图片      */     GlIDe.with(context).load(List.get(position).getimageUrl().get(0))         .overrIDe(dptopx(72),dptopx(72)).centerCrop().into(vIEwHolder.image);     if(List.get(position).getType().equals(News.TEXT_NEWS)){       vIEwHolder.digest.setText(List.get(position).getDigest());     } else {       vIEwHolder.digest.setText("");     }   } else if(holder instanceof ImageVIEwHolder){     ImageVIEwHolder vIEwHolder = (ImageVIEwHolder)holder;     vIEwHolder.Title.setText(List.get(position).getTitle());     vIEwHolder.time.setText(List.get(position).getTime());     setItemImage(vIEwHolder,List,position);   } else if(holder instanceof ProgressVIEwHolder){     ProgressVIEwHolder vIEwHolder = (ProgressVIEwHolder)holder;     vIEwHolder.progressbar.setIndeterminate(true);    } } 

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

看下Adapter的全部代码

package com.zmt.e_read.Adapter;  import androID.content.Context; import androID.support.v7.Widget.RecyclerVIEw; import androID.util.displayMetrics; import androID.vIEw.LayoutInflater; import androID.vIEw.VIEw; import androID.vIEw.VIEwGroup; import androID.Widget.ImageVIEw; import androID.Widget.TextVIEw;  import com.bumptech.glIDe.GlIDe; import com.zmt.e_read.Module.News; import com.zmt.e_read.Module.OnItemClickListener; import com.zmt.e_read.R; import com.zmt.e_read.Utils.ProgressVIEwHolder; import java.util.Collection; import java.util.Collections; import java.util.List; import butterknife.BindVIEw; import butterknife.ButterKnife;  /**  * Created by Dangelo on 2016/9/27.  */ public class NewsAdapter extends RecyclerVIEw.Adapter<RecyclerVIEw.VIEwHolder> {   private final int EMPTY_VIEW = 1;   private final int PROGRESS_VIEW = 2;   private final int IMAGE_VIEW = 3;   private Context context;   private List<News> List;   private OnItemClickListener clickListener;    public NewsAdapter(Context context,List<News> List,OnItemClickListener clickListener) {     this.context = context;     this.List = List;     this.clickListener = clickListener;   }    public voID addOnItemClickListener(OnItemClickListener clickListener){     this.clickListener = clickListener;   }    @OverrIDe   public int getItemVIEwType(int position) {     if(List.size() == 0){       return EMPTY_VIEW;     } else if(List.get(position) == null){       return PROGRESS_VIEW;     } else if(List.get(position).getType().equals(News.IMAGE_NEWS)){       return IMAGE_VIEW;     } else {       return super.getItemVIEwType(position);     }   }    @OverrIDe   public RecyclerVIEw.VIEwHolder onCreateVIEwHolder(VIEwGroup parent,int vIEwType) {     VIEw vIEw;     if(vIEwType == PROGRESS_VIEW){       vIEw = LayoutInflater.from(parent.getContext()).inflate(R.layout.progressbar_item,false);       return new ProgressVIEwHolder(vIEw);     } else if(vIEwType == EMPTY_VIEW){       return null;     } else if(vIEwType == IMAGE_VIEW){       vIEw = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_news_item,false);       return new ImageVIEwHolder(vIEw);     } else {       vIEw = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item,false);       return new NewsVIEwHolder(vIEw);     }   }    @OverrIDe   public voID onBindVIEwHolder(RecyclerVIEw.VIEwHolder holder,final int position) {     holder.itemVIEw.setonClickListener(new VIEw.OnClickListener() {       @OverrIDe       public voID onClick(VIEw v) {         clickListener.onItemClick(v,position);       }     });     if(holder instanceof NewsVIEwHolder){       NewsVIEwHolder vIEwHolder = (NewsVIEwHolder)holder;       vIEwHolder.Title.setText(List.get(position).getTitle());       vIEwHolder.time.setText(List.get(position).getTime());       /**        * GlIDe加载图片        */       GlIDe.with(context).load(List.get(position).getimageUrl().get(0))           .overrIDe(dptopx(72),dptopx(72)).centerCrop().into(vIEwHolder.image);       if(List.get(position).getType().equals(News.TEXT_NEWS)){         vIEwHolder.digest.setText(List.get(position).getDigest());       } else {         vIEwHolder.digest.setText("");       }     } else if(holder instanceof ImageVIEwHolder){       ImageVIEwHolder vIEwHolder = (ImageVIEwHolder)holder;       vIEwHolder.Title.setText(List.get(position).getTitle());       vIEwHolder.time.setText(List.get(position).getTime());       setItemImage(vIEwHolder,position);     } else if(holder instanceof ProgressVIEwHolder){       ProgressVIEwHolder vIEwHolder = (ProgressVIEwHolder)holder;       vIEwHolder.progressbar.setIndeterminate(true);      }   }    public voID setItemImage(ImageVIEwHolder vIEwHolder,int position){     vIEwHolder.imageMIDdle.setVisibility(VIEw.VISIBLE);     vIEwHolder.imageRight.setVisibility(VIEw.VISIBLE);     displayMetrics displayMetrics = context.getResources().getdisplayMetrics();     if(List.get(position).getimageUrl().size() == 1){       GlIDe.with(context).load(List.get(position).getimageUrl().get(0))           .overrIDe(displayMetrics.wIDthPixels - dptopx(10),dptopx(90))           .centerCrop().into(vIEwHolder.imageleft);       vIEwHolder.imageMIDdle.setVisibility(VIEw.GONE);       vIEwHolder.imageRight.setVisibility(VIEw.GONE);     } else if(List.get(position).getimageUrl().size() == 2){       int imageWIDth = (displayMetrics.wIDthPixels - dptopx(20)) / 2;       GlIDe.with(context).load(List.get(position).getimageUrl().get(0))           .overrIDe(imageWIDth,dptopx(90))           .centerCrop().into(vIEwHolder.imageleft);       GlIDe.with(context).load(List.get(position).getimageUrl().get(1))           .overrIDe(imageWIDth,dptopx(90))           .centerCrop().into(vIEwHolder.imageMIDdle);       vIEwHolder.imageRight.setVisibility(VIEw.GONE);     } else if(List.get(position).getimageUrl().size() >= 3){       int imageWIDth = (displayMetrics.wIDthPixels - dptopx(30)) / 3;       GlIDe.with(context).load(List.get(position).getimageUrl().get(0))           .overrIDe(imageWIDth,dptopx(90))           .centerCrop().into(vIEwHolder.imageMIDdle);       GlIDe.with(context).load(List.get(position).getimageUrl().get(2))           .overrIDe(imageWIDth,dptopx(90))           .centerCrop().into(vIEwHolder.imageRight);     }   }    @OverrIDe   public int getItemCount() {     return List.size();   }    public int dptopx(float dp){     float px = context.getResources().getdisplayMetrics().density;     return (int)(dp * px + 0.5f);   }    class NewsVIEwHolder extends RecyclerVIEw.VIEwHolder{     @BindVIEw(R.ID.news_Title)TextVIEw Title;     @BindVIEw(R.ID.news_digest)TextVIEw digest;     @BindVIEw(R.ID.news_time)TextVIEw time;     @BindVIEw(R.ID.news_src)ImageVIEw image;      public NewsVIEwHolder(VIEw itemVIEw) {       super(itemVIEw);       ButterKnife.bind(this,itemVIEw);     }   }    class ImageVIEwHolder extends RecyclerVIEw.VIEwHolder{      @BindVIEw(R.ID.news_Title) TextVIEw Title;     @BindVIEw(R.ID.image_left) ImageVIEw imageleft;     @BindVIEw(R.ID.image_right) ImageVIEw imageRight;     @BindVIEw(R.ID.image_mIDdle) ImageVIEw imageMIDdle;     @BindVIEw(R.ID.news_time) TextVIEw time;      public ImageVIEwHolder(VIEw itemVIEw) {       super(itemVIEw);       ButterKnife.bind(this,itemVIEw);     }   }        class ProgressVIEwHolder extends RecyclerVIEw.VIEwHolder {     @BindVIEw(R.ID.progressbar) Progressbar progressbar;     @BindVIEw(R.ID.textVIEw) TextVIEw textVIEw;      public ProgressVIEwHolder(VIEw itemVIEw) {       super(itemVIEw);       ButterKnife.bind(this,itemVIEw);     }   } }

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

最后说一下为什么为什么用RecyclerVIEw取代ListVIEw。

用过ListVIEw的都知道,在ListVIEw中若要复用视图缓存,就要在getVIEw()方法中手动判断convertVIEw是否为空,若不为空则复用视图缓存,若为空则重新加载视图,而RecyclerVIEw相当于对ListVIEw的Adapter进行了再次封装,把ListVIEw手动判断是否有缓存的代码封装到RecyclerVIEw内部,使这部分逻辑不可见,我们只需要通过getItemCount()方法告诉RecyclerVIEw有多少项数据,然后在onCreateVIEwHolder()中加载item布局实例化VIEwHolder,然后在onBindVIEwHolder()中完成数据的绑定即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android RecyclerView实现多种item布局的方法全部内容,希望文章能够帮你解决Android RecyclerView实现多种item布局的方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1143458.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存