RecyclerView的多种布局MultiItemTypeAdapter

为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)

你可能感兴趣的:(日常,封装)