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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Kotlin实现RecyclerView多种item布局,需要创建多个ViewHolder来适配不同的布局类型。具体步骤如下: ```kotlin // 创建一个通用的ViewHolder类 class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { // 绑定数据的方法 fun bindData(data: Any) { // 根据不同的数据类型,绑定不同的布局 when (data) { is TypeA -> { // 绑定TypeA布局 } is TypeB -> { // 绑定TypeB布局 } // ... } } } // 创建一个通用的Adapter类 class BaseAdapter(private val dataList: List<Any>) : RecyclerView.Adapter<BaseViewHolder>() { // 根据不同的布局类型,创建不同的ViewHolder override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { return when (viewType) { TYPE_A -> { // 创建TypeA布局的ViewHolder } TYPE_B -> { // 创建TypeB布局的ViewHolder } // ... else -> { // 创建默认布局的ViewHolder } } } // 根据不同的数据类型,返回不同的布局类型 override fun getItemViewType(position: Int): Int { return when (dataList[position]) { is TypeA -> TYPE_A is TypeB -> TYPE_B // ... else -> DEFAULT_TYPE } } // 绑定数据到ViewHolder override fun onBindViewHolder(holder: BaseViewHolder, position: Int) { holder.bindData(dataList[position]) } // 返回数据列表的大小 override fun getItemCount(): Int { return dataList.size } companion object { // 定义不同的布局类型 private const val TYPE_A = 0 private const val TYPE_B = 1 // ... private const val DEFAULT_TYPE = -1 } } ``` 在上述代码中,我们创建了一个通用的ViewHolder类和一个通用的Adapter类。ViewHolder类中的bindData方法根据不同的数据类型,绑定不同的布局。Adapter类中的getItemViewType方法根据不同的数据类型,返回不同的布局类型。在onCreateViewHolder方法中,根据不同的布局类型,创建不同的ViewHolder。在onBindViewHolder方法中,将数据绑定到ViewHolder上。最后,在RecyclerView中设置Adapter即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值