为RecyclerView添加多种布局,MultiItemTypeAdapter,文章很详细,篇幅比较长,请耐心看完
思路:
(1).数据源List 中每条item,即T 有可能对应不同的布局模式,这就是的Recyclerview中出现了多布局,在此,我们定义一个接口管理每条item的布局,如下:
public interface ItemViewDelegate
{
int getItemViewLayoutId();
boolean isForViewType(T item, int position);
void convert(ViewHolder holder, T t, int position);
}
注意:
boolean isForViewType(T item, int position); 是当符合某一条件时就使用这个布局,比如数据 T.getID = 1; 就是说你自己规定一个满足使用此布局的条件,并且该条件通常跟数据源T有关;
int getItemViewLayoutId(); 返回符合条件的布局的id
void convert(ViewHolder holder, T t, int position); holder做操作
进一步演示,首先我们创建实体类,如下:
public class ChatMessage
{
private int icon;
private String name;
private String content;
private String createDate;
private boolean isComMeg;
public final static int RECIEVE_MSG = 0;
public final static int SEND_MSG = 1;
public ChatMessage(int icon, String name, String content,
String createDate, boolean isComMeg)
{
this.icon = icon;
this.name = name;
this.content = content;
this.createDate = createDate;
this.isComMeg = isComMeg;
}
public boolean isComMeg()
{
return isComMeg;
}
public void setComMeg(boolean isComMeg)
{
this.isComMeg = isComMeg;
}
public String getContent()
{
return content;
}
public void setContent(String content)
{
this.content = content;
}
public int getIcon()
{
return icon;
}
public void setIcon(int icon)
{
this.icon = icon;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getCreateDate()
{
return createDate;
}
public void setCreateDate(String createDate)
{
this.createDate = createDate;
}
@Override
public String toString()
{
return "ChatMessage [icon=" + icon + ", name=" + name + ", content="
+ content + ", createDate=" + createDate +", isComing = "+ isComMeg()+ "]";
}
public static List MOCK_DATAS = new ArrayList<>();
static {
ChatMessage msg = null;
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.renma, "renma", "where are you ",
null, true);
MOCK_DATAS.add(msg);
msg = new ChatMessage(R.drawable.xiaohei, "xiaohei", "where are you ",
null, false);
MOCK_DATAS.add(msg);
}
}
那么,我们如何创建多种布局呢?做法如下:
public class MsgSendItemDelagate implements ItemViewDelegate
{
@Override
public int getItemViewLayoutId()
{
return R.layout.main_chat_send_msg;
}
@Override
public boolean isForViewType(ChatMessage item, int position)
{
//直接返回true就是不考虑数据对布局的影响,直接都使用单种布局
return item.isComMeg();//单条数据 (当这条数据的isComMeg是ture就符合这个布局)
}
@Override
public void convert(ViewHolder holder, final ChatMessage chatMessage, int position)
{
holder.setText(R.id.chat_send_content, chatMessage.getContent());
holder.setText(R.id.chat_send_name, chatMessage.getName());
holder.setImageResource(R.id.chat_send_icon, chatMessage.getIcon());
}
}
思路
(2).到此我们可以创建不同的布局,但是,创建完布局之后我们如何管理呢?这就需要一个管理者,它就是ItemViewDelegateManager,在此挑主要方法讲解
public class ItemViewDelegateManager
{
//布局管理者的集合
SparseArrayCompat> delegates = new SparseArrayCompat();
public int getItemViewDelegateCount()
{
return delegates.size();
}
//添加类型
public ItemViewDelegateManager addDelegate(ItemViewDelegate delegate)
{
int viewType = delegates.size();
if (delegate != null)
{
delegates.put(viewType, delegate);
viewType++;
}
return this;
}
public int getItemViewType(T item, int position)
{
//获取布局类型的个数
int delegatesCount = delegates.size();
for (int i = delegatesCount - 1; i >= 0; i--)
{
//获取一种布局
ItemViewDelegate delegate = delegates.valueAt(i);
//在上面说到的MsgSendItemDelagate类里面,当数据 return item.isComMeg();
if (delegate.isForViewType( item, position))
{
return delegates.keyAt(i);
}else{
}
}
throw new IllegalArgumentException(
"No ItemViewDelegate added that matches position=" + position + " in data source");
}
到此,基本的难点就将完了,尼玛,累了,后面再写。
最后附上鸿洋大神的地址:[来自鸿洋](https://github.com/hongyangAndroid/baseAdapter)