RecyclerView中的ViewType

来源:互联网 发布:dpyz是啥网络用语 编辑:程序博客网 时间:2024/06/05 18:19

RecyclerView中的ViewType

1. 前言

    在接触了RecyclerView了之后,就慢慢的用它代替了ListView的使用,结合CardView能创建出比较好看的列表,但是这根本就不够诶,单纯的列表好像没什么意思了,好多应用的信息量比较大而且很复杂,每个item需要用到不同的布局文件来显示不同的信息= =,之前写来写去都是简单的列表,根本就没接触到ViewType这个东西,稍微熟悉并使用了之后,才发现= =RecyclerView还可以这样用噢(原谅我的无知)。

    看下面的这张图= =,豌豆荚里面的列表项,基本上每个item都不一样,下面用一个自己弄的小demo来演示如何在一个RecyclerView中实现多个item。

2. ViewType使用方法

    RecyclerView中的ViewType就是一个int类型的数字,用来将每个item归类,同一类的item使用着同一套布局文件,我们都知道使用RecyclerView的时候会用到Adapter,还会用到ViewHolder。一个ViewHolder对应着一类布局文件,也就是对应着一类item,还需要用Adapter来针对不同的ViewHolder来绑定不同的数据。

2.1 定义不同种类的item视图

    先定义了三种item的xml视图,在这里就不给出了,非常简单的布局,随便自己定义下就好了。对应的需要定义三种不同的ViewHolder:

class ViewHolderOne extends RecyclerView.ViewHolder {    @Bind(R.id.item_recyclerview_demo_user_avatar)    public ImageView mUserAvatar;    @Bind(R.id.item_recyclerview_demo_user_name)    public TextView mUserName;    @Bind(R.id.item_recyclerview_demo_user_info)    public TextView mUserInfo;    @Bind(R.id.item_recyclerview_demo_selected)    public ImageView mSelected;    public ViewHolderOne(View view) {      super(view);      ButterKnife.bind(this, view);    }  }  class ViewHolderTwo extends RecyclerView.ViewHolder {    @Bind(R.id.item_recyclerview_demo_user_avatar)    public ImageView mUserAvatar;    @Bind(R.id.item_recyclerview_demo_user_name)    public TextView mUserName;    @Bind(R.id.item_recyclerview_demo_user_info)    public TextView mUserInfo;    @Bind(R.id.item_recyclerview_demo_selected)    public ImageView mSelected;    public ViewHolderTwo(View view) {      super(view);      ButterKnife.bind(this, view);    }  }  class ViewHolderThree extends RecyclerView.ViewHolder {    @Bind(R.id.item_recyclerview_demo_user_avatar)    public ImageView mUserAvatar;    @Bind(R.id.item_recyclerview_demo_user_name)    public TextView mUserName;    @Bind(R.id.item_recyclerview_demo_user_info)    public TextView mUserInfo;    @Bind(R.id.item_recyclerview_demo_selected)    public ImageView mSelected;    public ViewHolderThree(View view) {      super(view);      ButterKnife.bind(this, view);    }  }

    为了图个方便,三种布局里面主要的控件都是一样的,只是有些地方不同,具有id的一些控件都是相同的,所以ViewHolder中的东西都是一样的,也可以根据自己不同的需求来定义完全不同的ViewHolder(千万不要受我的影响 = =)。

2.2 自定义Adapter

    定义好了三种ViewHolder之后,就需要根据不同的需求,在Adapter里面识别并运用这些ViewHolder,Adapter里面已经定义好了一些方法,只需要重写getItemViewType(int position)方法,给每个固定的position上的item返回一个固定的类型(ViewType)就能方便的表明每个item需要的ViewHolder。

class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {    //User是一个自定义类,代表封装的数据类型    private List<User> mUsers;    //三种不同的ViewType类型,事先用常量定义好    public static final int VIEW_TYPE_ONE = 1;    public static final int VIEW_TYPE_TWO = 2;    public static final int VIEW_TYPE_THREE = 3;    public MyAdapter(List<User> users) {      mUsers = users;    }    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {      RecyclerView.ViewHolder myViewHolder = null;    //根据不同的ViewType类型,来返回不同的ViewHolder      switch (viewType) {        case VIEW_TYPE_ONE:          myViewHolder = new ViewHolderOne              (LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item_one, parent, false));        break;        case VIEW_TYPE_TWO:          myViewHolder = new ViewHolderTwo              (LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item_two, parent, false));          break;        case VIEW_TYPE_THREE:          myViewHolder = new ViewHolderThree              (LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item_three, parent, false));          break;      }      return myViewHolder;    }    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {    //根据不同的ViewType类型,进行不同的数据绑定操作      switch (holder.getItemViewType()) {        case VIEW_TYPE_ONE:          ViewHolderOne holderOne = (ViewHolderOne) holder;          holderOne.mUserAvatar.setImageResource(R.mipmap.ic_launcher);          holderOne.mUserName.setText(mUsers.get(position).getUserName());          holderOne.mUserInfo.setText(mUsers.get(position).getInfo());          break;        case VIEW_TYPE_TWO:          ViewHolderTwo holderTwo = (ViewHolderTwo) holder;          holderTwo.mUserAvatar.setImageResource(R.mipmap.user_avatar);          holderTwo.mUserName.setText(mUsers.get(position).getUserName());          holderTwo.mUserInfo.setText(mUsers.get(position).getInfo());          break;        case VIEW_TYPE_THREE:          ViewHolderThree holderThree = (ViewHolderThree) holder;          holderThree.mUserAvatar.setImageResource(R.mipmap.ic_launcher);          holderThree.mUserName.setText(mUsers.get(position).getUserName());          holderThree.mUserInfo.setText(mUsers.get(position).getInfo());          break;      }    }    @Override    public int getItemCount() {      if (null != mUsers) return mUsers.size();      else return 0;    }    //重写方法,给每个position上的item返回一个固定的ViewType类型    //如果返回的ViewType类型不固定,则会出现各种item布局变化的情况,可能还会触发bug    @Override    public int getItemViewType(int position) {      return mUsers.get(position).getType();    }  }

在Adapter里面涉及到了一个User.java的数据类型,下面是其代码:

public class User implements Parcelable {  private int type;  private String info;  private String userName;  public int getType() {    return type;  }  public void setType(int type) {    this.type = type;  }  public String getInfo() {    return info;  }  public void setInfo(String info) {    this.info = info;  }  public String getUserName() {    return userName;  }  public void setUserName(String userName) {    this.userName = userName;  }  public User() {  }  public User(int t, String u, String i) {    type = t;    userName = u;    info = i;  }}

2.3 使用定义好了的Adapter

    一切都准备好了,只需要将Adapter给RecyclerView装上就可以了。再装上一个用来下拉刷新添加数据的控件。

mAdapter = new MyAdapter(mUsers);    mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));    mRecyclerView.setItemAnimator(new DefaultItemAnimator());    mRecyclerView.setAdapter(mAdapter);

使用的效果如下,再加以细节上的处理,一个拥有多个ViewType的RecyclerView就诞生了= =:

1 0
原创粉丝点击