当我们使用RecylerView时,需要绑定一个Adapter和LayoutManager,而vlayout里定义了VirtualLayoutAdapter(继承自Adapter)和VirtualLayoutManager(继承自LayoutManager)来绑定到RecyclerView。
它是一个抽象类,很简单:
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 helpers) {
this.mLayoutManager.setLayoutHelpers(helpers);
}
@NonNull
// 获取整个页面一系列的LayoutHelper
public List getLayoutHelpers() {
return this.mLayoutManager.getLayoutHelpers();
}
}
其中setLayoutHelpers()和getLayoutHelpers()具体实现委托给VirtualLayoutManager来完成。
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
我们要传递数据集给子Adapter,同时实现onCreateViewHolder(),onBindViewHolder(),getItemCount(),看上去和实现普通的RecyclerView的Adapter一模一样。
当然我们还必须实现onCreateLayoutHelper()这个抽象方法,返回该Adapter对应的LayoutHelper(用于给子Adapter对应的UI模块布局)。
@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()。
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()。
我们在设置子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。