RecyclerView多种Item类型的消息展示
2017-03-30 17:29
369 查看
一.写在前面
公司需要做一个消息列表,并且说明,有三种类型。图文,单独图片,单独文字。UI设计图如下。完成后感觉学到点平常没注意的。抽出部分代码做成demo效果如下二.干货
大致思路就是通过是否有图片或者文字数据进行判断类型。1.布局直接贴个图文布局的xml,学到了里面有个textview的属性平常用的比较少。android:lineSpacingExtra=”2dp” ,用它来设置文字行间距。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_gravity="center" android:background="@color/backgroundGray" android:layout_width="match_parent" android:layout_height="wrap_content"> <RelativeLayout android:layout_marginTop="@dimen/y30" android:background="@drawable/bg_gray_rect" android:gravity="center" android:layout_gravity="center_horizontal" android:layout_width="@dimen/x160" android:layout_height="@dimen/y44"> <TextView android:textSize="@dimen/y22" android:text="03-18 17:19" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout> <LinearLayout android:background="@drawable/bg_blue_rect_raduis" android:layout_marginRight="@dimen/x30" android:layout_marginLeft="@dimen/x30" android:layout_marginTop="@dimen/y30" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/tv_item_message_title" android:layout_marginBottom="@dimen/y20" android:layout_marginTop="@dimen/y20" android:layout_marginLeft="@dimen/x30" android:textColor="@color/black" android:textSize="@dimen/y28" android:text="WE今晚打IG" android:lines="1" android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_item_message_time" android:layout_marginBottom="@dimen/y30" android:layout_marginLeft="@dimen/x30" android:textColor="@color/public_gray" android:textSize="@dimen/y22" android:text="2017-03-18" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <View android:layout_marginLeft="@dimen/x30" android:layout_marginRight="@dimen/x30" android:background="@color/public_gray" android:layout_width="match_parent" android:layout_height="0.5dp" /> <TextView android:id="@+id/tv_item_message_content" android:layout_marginBottom="@dimen/y14" android:layout_marginLeft="@dimen/x30" android:layout_marginRight="@dimen/x30" android:layout_marginTop="@dimen/y11" android:textColor="@color/black" android:textSize="@dimen/y26" android:lineSpacingExtra="2dp" android:text="今晚we打ig看不看,看不看点点滴滴地对地导弹,不看算了,草莓一样送了易学,dddd,啊什么we解散了" android:lines="2" android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/iv_item_message_imglogo" android:layout_marginBottom="@dimen/y16" android:layout_marginTop="@dimen/y16" android:layout_gravity="center_horizontal" android:layout_width="@dimen/x194" android:layout_height="@dimen/y256" /> <View android:layout_marginLeft="@dimen/x30" android:layout_marginRight="@dimen/x30" android:background="@color/public_gray" android:layout_width="match_parent" android:layout_height="0.5dp" /> <RelativeLayout android:layout_marginLeft="@dimen/x30" android:layout_marginRight="@dimen/x30" android:layout_marginBottom="@dimen/y30" android:layout_marginTop="@dimen/y20" android:gravity="center_vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:textColor="@color/black" android:textSize="@dimen/y28" android:text="立即查看" android:lines="1" android:ellipsize="end" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:layout_centerVertical="true" android:layout_alignParentRight="true" android:src="@mipmap/icon_arrow_right" android:layout_width="@dimen/x14" android:layout_height="@dimen/y24" /> </RelativeLayout> </LinearLayout> </LinearLayout>
2.主要重点在adapter。首先adapter继承RecyclerView.Adapter时它的泛型和平常不一样,平常adapter里面只有一个ViewHolder,泛型直接用单独一个的ViewHolder即可。但是这里我自定义了三种ViewHolder,所以这里选择使用它的父类最初的RecyclerView.ViewHolder。后面用自定义的类去将父类强转成自己的。
public class MessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ }
将自己的三种类型的ViewHolder类写出来
class ViewHolderDouble extends RecyclerView.ViewHolder{ View vhd; TextView tv_item_message_title; TextView tv_item_message_time; TextView tv_item_message_content; ImageView iv_item_message_imglogo; public ViewHolderDouble(View itemView) { super(itemView); vhd = itemView; tv_item_message_title = (TextView) itemView.findViewById(R.id.tv_item_message_title); tv_item_message_time = (TextView) itemView.findViewById(R.id.tv_item_message_time); tv_item_message_content = (TextView) itemView.findViewById(R.id.tv_item_message_content); iv_item_message_imglogo = (ImageView) itemView.findViewById(R.id.iv_item_message_imglogo); } } class ViewHolderSingelContent extends RecyclerView.ViewHolder{ View vhc; TextView tv_item_message_title; TextView tv_item_message_time; TextView tv_item_message_content; public ViewHolderSingelContent(View itemView) { super(itemView); vhc = itemView; tv_item_message_title = (TextView) itemView.findViewById(R.id.tv_item_message_title); tv_item_message_time = (TextView) itemView.findViewById(R.id.tv_item_message_time); tv_item_message_content = (TextView) itemView.findViewById(R.id.tv_item_message_content); } } class ViewHolderSingelImg extends RecyclerView.ViewHolder{ View vhi; TextView tv_item_message_title; TextView tv_item_message_time; ImageView iv_item_message_imglogo; public ViewHolderSingelImg(View itemView) { super(itemView); vhi = itemView; tv_item_message_title = (TextView) itemView.findViewById(R.id.tv_item_message_title); tv_item_message_time = (TextView) itemView.findViewById(R.id.tv_item_message_time); iv_item_message_imglogo = (ImageView) itemView.findViewById(R.id.iv_item_message_imglogo); } }
要使用getItemViewType,因为它返回的是int类型,所以我先定义三个属性
private static final int MESSAGE_ADAPTER_TYPE_DOUBLE = 0000; //图文 private static final int MESSAGE_ADAPTER_TYPE_SINGLECONTENT = 1111; //只有内容 private static final int MESSAGE_ADAPTER_TYPE_IMG = 2222; //只有图片
3. 正如前面说的,通过数据来判断类型。所以这里的代码比较简单,直接判断有没有相应的数据,然后返回相应的类型码,bean字段代码一起贴出来。
private String title; //标题 private String time; //时间 private String content; //内容 private String imgUrl; //图片
/** * 判断集合中某一对象content,img两个是否有数据,根据不同情况返回类型识别码,用于加载不同的布局 * @param position * @return */ @Override public int getItemViewType(int position) { ItemMessageBean bean = messageBeanList.get(position); if(!TextUtils.isEmpty(bean.getContent())&&!TextUtils.isEmpty(bean.getImgUrl())){ //内容和图片数据都有 return MESSAGE_ADAPTER_TYPE_DOUBLE; }else if(TextUtils.isEmpty(bean.getContent())&&!TextUtils.isEmpty(bean.getImgUrl())){ //只有图片 return MESSAGE_ADAPTER_TYPE_IMG; }else if(!TextUtils.isEmpty(bean.getContent())&& TextUtils.isEmpty(bean.getImgUrl())){ //只有文字 return MESSAGE_ADAPTER_TYPE_SINGLECONTENT; } return -1; }
4. onCreateViewHolder中的两个参数中int viewType其实就是上面那个方法返回的int数据。所以对它进行判断,加载不同的布局。
if(viewType==MESSAGE_ADAPTER_TYPE_DOUBLE){ //都有类型 View viewDouble = LayoutInflater.from(mContext).inflate(R.layout.item_message_double,parent,false); final ViewHolderDouble viewHolderDouble = new ViewHolderDouble(viewDouble); viewHolderDouble.vhd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = viewHolderDouble.getAdapterPosition(); Toast.makeText(mContext,"我是点击事件,位置 "+position+" 标题-->"+messageBeanList.get(position).getTitle(),Toast.LENGTH_SHORT).show(); } }); return viewHolderDouble; }else if(viewType==MESSAGE_ADAPTER_TYPE_SINGLECONTENT){ //只有内容 View viewSingleContent = LayoutInflater.from(mContext).inflate(R.layout.item_message_singlecontent,parent,false); final ViewHolderSingelContent viewHolderContent = new ViewHolderSingelContent(viewSingleContent); viewHolderContent.vhc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = viewHolderContent.getAdapterPosition(); Toast.makeText(mContext,"我是点击事件,位置 "+position+" 标题-->"+messageBeanList.get(position).getTitle(),Toast.LENGTH_SHORT).show(); } }); return viewHolderContent; }else if(viewType==MESSAGE_ADAPTER_TYPE_IMG){ //只有图片 View viewSingleImg = LayoutInflater.from(mContext).inflate(R.layout.item_message_singleimg,parent,false); final ViewHolderSingelImg viewHolderImg = new ViewHolderSingelImg(viewSingleImg); viewHolderImg.vhi.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = viewHolderImg.getAdapterPosition(); Toast.makeText(mContext,"我是点击事件,位置 "+position+" 标题-->"+messageBeanList.get(position).getTitle(),Toast.LENGTH_SHORT).show(); } }); return viewHolderImg; }
5. 正如前面所说的,因为泛型是RecyclerView.ViewHolder,所以在绑定数据的方法中onBindViewHolder(RecyclerView.ViewHolder holder, int position),给我们自动生成的RecyclerView.ViewHolder holder对象也是父类的对象,对这个对象进行判断,判断这个对象是不是自己定义的三个子类的的实例,如果是则强转父类holder对象成子类的实例。
/** * 因为这个类继承的RecyclerView.Adapter<RecyclerView.ViewHolder>泛型是父类的ViewHolder, * 所以这里返回的holder,也是最初的,需要对我们自己定义的三个viewholder判断,判断这个holder对象是自己定义的三个类的实例,然后根据自己需要的 * ViewHolder获取控件,绑定数据 * @param holder * @param position */ @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { ItemMessageBean bean = messageBeanList.get(position); if(holder instanceof ViewHolderDouble){ ViewHolderDouble vhd = (ViewHolderDouble) holder; vhd.tv_item_message_title.setText(bean.getTitle()); vhd.tv_item_message_time.setText(bean.getTime()); vhd.tv_item_message_content.setText(bean.getContent()); //加载图片这里我使用picasso,按道理这种列表中的图片加载使用fresco比较好 Picasso.with(mContext).load(bean.getImgUrl()).into(vhd.iv_item_message_imglogo); }else if(holder instanceof ViewHolderSingelContent){ ViewHolderSingelContent vhc = (ViewHolderSingelContent) holder; vhc.tv_item_message_title.setText(bean.getTitle()); vhc.tv_item_message_time.setText(bean.getTime()); vhc.tv_item_message_content.setText(bean.getContent()); }else if(holder instanceof ViewHolderSingelImg){ ViewHolderSingelImg vhi = (ViewHolderSingelImg) holder; vhi.tv_item_message_title.setText(bean.getTitle()); vhi.tv_item_message_time.setText(bean.getTime()); Picasso.with(mContext).load(bean.getImgUrl()).into(vhi.iv_item_message_imglogo); } }
6. 使用直接自己生成几个数据,
/** * 获取消息数据源 */ private void requestMessageData(){ messageItemList = new ArrayList<>(); ItemMessageBean bean1 = new ItemMessageBean(); bean1.setTitle("今晚WE打IG"); bean1.setTime("2017-03-30"); bean1.setContent("今晚we打ig看不看,看不看点点滴滴地对地导弹,不看算了,草莓一样送了易学,dddd,啊什么we解散了"); bean1.setImgUrl("http://img5.dwstatic.com/lol/1601/315942968863/1451987776988.png"); ItemMessageBean bean2 = new ItemMessageBean(); bean2.setTitle("今晚打老虎"); bean2.setTime("2017-03-30"); bean2.setImgUrl("https://poyeedotme.files.wordpress.com/2012/07/20120727tiger.jpg?w=500&h=375"); ItemMessageBean bean3 = new ItemMessageBean(); bean3.setTitle("今晚也不知道干什么"); bean3.setTime("2017-03-30"); bean3.setContent("多了几分武功额文件给我切我额过后id为给外婆了各位好的few额个猥琐的几个忘了换个i我欸和工委和你宋伟额维护功能死"); messageItemList.add(bean1); messageItemList.add(bean2); messageItemList.add(bean3); }
对recyclerview初始化和加载适配器
private void initView() { requestMessageData(); recyMessageSystem = (RecyclerView) this.findViewById(R.id.recyMessageSystem); recyMessageSystem.setLayoutManager(new LinearLayoutManager(this)); MessageAdapter adapter = new MessageAdapter(messageItemList, this); recyMessageSystem.setAdapter(adapter); }
3. 下载地址
源码地址相关文章推荐
- RecyclerView 展示多种类型Item数据
- RecyclerView不同类型Item的展示
- RecyclerView多种item类型头部底部
- [置顶] RecyclerView实现加载多种条目类型,仿新闻列表多种item布局.
- 一个RecyclerView列表显示多种类型的Item
- RecyclerView的Item多种类型的选择之普通方法实现
- 让多种类型item的Recyclerview能够上拉和下拉刷新--XRefreshView
- RecyclerView用法(一)------展示多中类型Item数据
- RecyclerView用法(一)------展示单一类型Item数据
- listview里面的item的多种view模式(多种类型的item)
- RecyclerView实现瀑布流遇到的各种问题(item移动,加载更多图片闪烁,以及定制各种类型Header和Footer)
- android图文混排与多种类型listView的混搭的item的demo,getItemViewType()和getViewTypeCount()的使用
- Kotlin实战(二): 实现RecyclerView多种Item布局
- RecyclerView展示多种布局
- Android RecyclerView 加载更多数据 及 不同类型itemView的使用
- BaseRecyclerViewAdapterHelper开源项目之BaseMultiItemQuickAdapter 实现多类型源码学习
- 【Android 编程架构 程序设计】多Item类型的RecyclerView替代scrollView(附demo)
- RecyclerView 获取滑动停止时展示出的item范围
- Android中Recyclerview使用13----实现瀑布流遇到的各种问题(item移动,加载更多图片闪烁,以及定制各种类型Header和Footer)
- RecyclerView使用(二)多种Item布局、添加点击事件