RecyclerView实现吸顶效果项目实战(四):RecyclerView原理解析

本文通过源码分析,探讨RecyclerView与ListView的区别,详细解释了RecyclerView如何进行布局、缓存View,以及滑动过程的工作原理,展示了RecyclerView在滚动布局和View复用方面的优势。
摘要由CSDN通过智能技术生成

一、引言

在平时的开发过程中,当用到滑动布局时,我们用的比较多的是ListView或ScrollView,但对于RecyclerView的使用却比较少,也就是在需要用到水平滑动布局时才会想到RecyclerView。那在有了ListView的情况下,为什么Google还要推出RecyclerView呢?下面我们从源码角度来分析一下该RecyclerView的布局与缓存原理,看看其与ListView有什么区别。

二、源码分析

RecyclerView 一般使用方式是在 Layout 中定义布局文件,然后在 Activity 中通过findViewById 来拿到 RecyclerView 的实例对象,因此我们从 RecyclerView 的构造函数入手进行分析。

public RecyclerView() {
    ...
    if (attrs != null) {
        int defStyleRes = 0;
        TypedArray a = context.obtainStyledAttributes(attrs, styleable.RecyclerView, defStyle, defStyleRes);
        String layoutManagerName = a.getString(styleable.RecyclerView_layoutManager);
        ...
        a.recycle();
        this.createLayoutManager(context, layoutManagerName, attrs, defStyle, defStyleRes);
        ...
    } 
    ...
}

构造函数中告诉我们,可以在布局文件中通过 app:layoutManager 来设置 RecyclerViewLayoutManager 对象。LayoutManager 主要负责 RecyclerView 的布局。

拿到 RecyclerView 对象后,如果在构造函数中没有设置 LayoutManager,可以通过调用 RecyclerViewsetLayoutManager(RecyclerView.LayoutManager layout) 方法进行设置。

public void setLayoutManager(RecyclerView.LayoutManager layout) {
    if (layout != this.mLayout) {
        ...
        this.mLayout = layout;   
        ...       
    }
}

然后 RecyclerView 会调用 setAdapter 方法。

public void setAdapter(RecyclerView.Adapter adapter) {
    this.setLayoutFrozen(false);
    this.setAdapterInternal(adapter, false, true);
    this.requestLayout();
}

setAdapterInternal 方法主要作用是将传进来的 adapter 保存到 mAdapter 变量。之后调用了 requestLayout 方法。

public void requestLayout() {
    if (this.mEatRequestLayout == 0 && !this.mLayoutFrozen) {
        super.requestLayout();
    } else {
        this.mLayoutRequestEaten = true;
    }
}

requestLayout 方法又调用了父类的 requestLayout 方法,最终调用了 ViewrequestLayout 方法。

public void requestLayout() {
    ...
    if (mParent != null && !mParent.isLayoutRequested()) {
        mParent.requestLayout();
    }
    ...
}

上面的 mParent 的真正实例为 ViewRootImpl,也就是说执行了 ViewRootImplrequestLayout 方法。

public void requestLayout() {
    if (!mHandlingLayoutInLayoutRequest) {
        checkThread();
        mLayoutReque
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值