前言
當我們使用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。