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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值