当我们使用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模块布局)。
@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()。
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。