vlayout原理分析

前言

當我們使用RecylerView時,需要綁定一個Adapter和LayoutManager,而vlayout裏定義了VirtualLayoutAdapter(繼承自Adapter)和VirtualLayoutManager(繼承自LayoutManager)來綁定到RecyclerView。

VirtualLayoutAdapter

它是一個抽象類,很簡單:

public abstract class VirtualLayoutAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {

    @NonNull
    protected VirtualLayoutManager mLayoutManager;

    public VirtualLayoutAdapter(@NonNull VirtualLayoutManager layoutManager) {
        this.mLayoutManager = layoutManager;
    }

    // 設置整個頁面一系列的LayoutHelper
    public void setLayoutHelpers(List<LayoutHelper> helpers) {
        this.mLayoutManager.setLayoutHelpers(helpers);
    }

    @NonNull
    // 獲取整個頁面一系列的LayoutHelper
    public List<LayoutHelper> getLayoutHelpers() {
        return this.mLayoutManager.getLayoutHelpers();
    }

}

其中setLayoutHelpers()和getLayoutHelpers()具體實現委託給VirtualLayoutManager來完成。

DelegateAdapter

VirtualLayoutAdapter有一個唯一實現子類DelegateAdapter,顧名思義,它是一個代理的Adapter。我們一般使用vlayout的時候,會給RecyclerView綁定一個VirtualLayoutAdapter,就是這個已經實現好了的DelegateAdapter。

它的作用是什麼呢?管理所有的子Adapter(DelegateAdapter.Adapter)
因爲我們使用vlayout的時候,將DelegateAdapter和VirtualLayoutManager綁定到RecyclerView之後,要做的事情就是給DelegateAdapter設置一個子Adapter的集合

DelegateAdapter.Adapter

    public static abstract class Adapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
        public abstract LayoutHelper onCreateLayoutHelper();

        protected void onBindViewHolderWithOffset(VH holder, int position, int offsetTotal) {

        }

        protected void onBindViewHolderWithOffset(VH holder, int position, int offsetTotal, List<Object> payloads) {
            onBindViewHolderWithOffset(holder, position, offsetTotal);
        }
    }

我們要傳遞數據集給子Adapter,同時實現onCreateViewHolder(),onBindViewHolder(),getItemCount(),看上去和實現普通的RecyclerView的Adapter一模一樣。

當然我們還必須實現onCreateLayoutHelper()這個抽象方法,返回該Adapter對應的LayoutHelper(用於給子Adapter對應的UI模塊佈局)。

DelegateAdapter的onCreateViewHolder()

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        if (mHasConsistItemType) {
            Adapter adapter = mItemTypeAry.get(viewType);
            if (adapter != null) {
                return adapter.onCreateViewHolder(parent, viewType);
            }

            return null;
        }


        // reverse Cantor Function
        Cantor.reverseCantor(viewType, cantorReverse);

        int index = (int)cantorReverse[1];
        int subItemType = (int)cantorReverse[0];

        Adapter adapter = findAdapterByIndex(index);
        if (adapter == null) {
            return null;
        }

        return adapter.onCreateViewHolder(parent, subItemType);
    }

其中關鍵的一句就是Adapter adapter = findAdapterByIndex(index);,它會去找到該viewType對應的子Adapter,然後調用對應子Adapter的onCreateViewHolder()。

DelegateAdapter的onBindViewHolder()

    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List<Object> payloads) {
        super.onBindViewHolder(holder, position, payloads);
        Pair<AdapterDataObserver, Adapter> pair = findAdapterByPosition(position);
        if (pair == null) {
            return;
        }
        pair.second.onBindViewHolder(holder, position - pair.first.mStartPosition, payloads);
        pair.second.onBindViewHolderWithOffset(holder, position - pair.first.mStartPosition, position, payloads);

    }

這裏其實也是去找到了對應的子Adapter,並且調用應子Adapter的onBindViewHolder()。

VirtualLayoutManager

我們在設置子Adapter的時候都會創建對應的LayoutHelper,在給DelegateAdapter設置Adapter的時候,會將LayoutHelper的集合傳遞給VirtualLayoutManager。

VirtualLayoutManager的作用就是管理LayoutHelper的集合,並且負責RecyclerView的佈局

瞭解過RecyclerView的話,應該就知道RecyclerView執行onLayout()的時候,會調用LayoutManager的onLayoutChildren()。

VirtualLayoutManager的onLayoutChildren()會調用fill(),fill()中又去調用layoutChunk(),其中有這麼一句layoutHelper.doLayout(recycler, state, mTempLayoutStateWrapper, result, this);,這裏就是找到對應LayoutHelper,讓LayoutHelper調用layoutViews()去執行具體的佈局。

以上就是對vlayout的原理分析,關於vlayout的概述可以參考帶你學習阿里巴巴的開源庫VLayout

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章