您的位置:首页 > 其它

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. 下载地址

源码地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: