1. 程式人生 > >RecyclerView的多種佈局MultiItemTypeAdapter

RecyclerView的多種佈局MultiItemTypeAdapter

為RecyclerView新增多種佈局,MultiItemTypeAdapter,文章很詳細,篇幅比較長,請耐心看完

思路:
(1).資料來源List<T> 中每條item,即T 有可能對應不同的佈局模式,這就是的Recyclerview中出現了多佈局,在此,我們定義一個介面管理每條item的佈局,如下:

public interface ItemViewDelegate<T>
{

    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<ChatMessage> 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<ChatMessage> { @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<T>,在此挑主要方法講解
public class ItemViewDelegateManager<T>
{
    //佈局管理者的集合
    SparseArrayCompat<ItemViewDelegate<T>> delegates = new SparseArrayCompat();

    public int getItemViewDelegateCount()
    {
        return delegates.size();
    }

    //新增型別
    public ItemViewDelegateManager<T> addDelegate(ItemViewDelegate<T> 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<T> 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)