1. 说明
在我们实际开发过程中,有时候会有这样的需求,就是使用ListView或者RecyclerView显示一个列表,然后这个列表中的数据有多种布局的类型,这里就使用微信聊天来举例,而针对于这种多种布局类型的条目,后台一般都会给一个字段用来区分当前条目到底是什么类型的,如果后台没有这样一个字段用于区分当前显示哪种类型条目的话,那么这个需求是没有办法去做的。
在这里我们就采用微信聊天举例说明:
比如后台返回的数据是:chatContent 聊天内容 、isMe是否是我自己的
针对于这种多布局,解决方案一般是从对象下手,根据列表当前的条目来确定布局
其实主要还是getItemViewType(int position)方法
具体代码如下:
/**
* Created by JackChen on 2018/3/4.
* Description : RecyclerView多布局展示
*/
public class CommonAdapterActivity extends AppCompatActivity {
private RecyclerView recycler_view;
private List<ChatData> datas ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_use);
//测试数据
initData() ;
recycler_view = (RecyclerView) findViewById(R.id.recycler_view);
// 在setAdapter之前必须先设置布局的样式,否则数据不会显示的
recycler_view.setLayoutManager(new LinearLayoutManager(this));
recycler_view.setAdapter(new RecyclerAdapter(this,datas));
}
/**
* 测试数据
*/
private void initData() {
datas = new ArrayList<>() ;
for (int i = 0; i < 100; i++) {
if (i % 3 == 0){ // 1 表示是自己说的话
datas.add(new ChatData("内容"+i, 1)) ;
}else{
datas.add(new ChatData("内容"+i, 0)) ; // 0 表示别人说的话
}
}
}
private class RecyclerAdapter extends RecyclerCommonAdapter<ChatData>{
// // 单布局条目
// public RecyclerAdapter(Context context, List data, int layoutId) {
// super(context, data, layoutId);
// }
// 多布局显示
public RecyclerAdapter(Context context, List<ChatData> data) {
super(context, data, new MutiliTypeSupport<ChatData>() {
@Override
public int getLayoutId(ChatData item) {
// 如果自己项目中列表是多条目,直接写这个地方,这里需要做的就只是从服务器中取出判断多条目的字段,
// 这里为了方便测试,只是从测试数据中取出 字段isMe , 这里的isMe - 1表示自己,0表示朋友
if (item.isMe ==1){
return R.layout.item_chat_me ;
}
return R.layout.item_chat_friend;
}
});
}
@Override
protected void convert(ViewHolder holder, ChatData item, int position) {
holder.setText(R.id.chat_text , item.chatContent) ;
}
}
public class ChatData {
public ChatData(String content , int isMe){
this.chatContent = content ;
this.isMe = isMe ;
}
public String chatContent ;
public int isMe ; // 1 表示是我自己的 0 表示其他人
}
}
2. 步骤分析
2.1 先去请求网络数据,此处使用initData()测试数据来模拟网络请求;
2.2 然后给RecyclerView设置布局样式、并且自定义一个 RecyclerAdapter继承自己封装的万能Adapter,RecyclerCommonAdapter<ChatData> , 并且复写对应方法,这里注意注释的为单条目方法,下边的为多条目方法:
如果有2个不同类型的条目,那么就用if else 去判断;
如果有3个不同的条目,同样的在getLayoutId()中只去return R.layout.item_chat_xxx ,即可;
也就是说,不管它有多少个不同的布局,我们只需要在这里去用服务器返回的字段对应的值去判断需要加载对应的布局文件就行;
注意 item.isMe 是服务器返回来的变量,而这个字段会有对应的值,比如此处:
is.Me = 1 表示 加载 自己聊天内容的布局;
is.Me = 0 表示 加载 朋友聊天内容的布局;
同样的,在实际开发过程中,如果有加载不同类型条目的需求,就只需要从服务器返回的数据中取出这个字段,然后判断它对应的值是什么,然后我们只需要根据它对应的值去加载它对应的布局文件;
这里 is.Me = 1 表示 加载 自己聊天内容的布局;
is.Me = 0 表示 加载 朋友聊天内容的布局;
是服务器已经规定好了的,我们只需要去加载对应布局就行
2.3 convert()方法是设置数据;
具体代码我会在讲完 RecyclerView后整体上传至github。