RecyclerView实现多种item布局

来源:互联网 发布:淘宝上的华佗药房 编辑:程序博客网 时间:2024/05/18 19:22

在项目中列表是基本都会用到的,然而在显示列表时,我们需要的数据可能需要不止一种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, parent, false);            return new ImageViewHolder(view);        } else {            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, 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, 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, parent, false);            return new ImageViewHolder(view);        } else {            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, 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, list, position);        } else if(holder instanceof ProgressViewHolder){            ProgressViewHolder viewHolder = (ProgressViewHolder)holder;            viewHolder.progressBar.setIndeterminate(true);        }    }    public void setItemImage(ImageViewHolder viewHolder, List<News> list, 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.imageLeft);            Glide.with(context).load(list.get(position).getImageUrl().get(1))                    .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);        }    }            <pre name="code" class="java">    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

3 1
原创粉丝点击