RecyclerView原理解析

转载请注明:https://blog.youkuaiyun.com/feather_wch/article/details/79932523

参考和学习资料

  1. 自定义LayoutManager

  2. RecyclerView绘制流程解析

  3. LinearLayoutManager填充、测量、布局过程

  4. 掌握自定义LayoutManager(一) 系列开篇 常见误区、问题、注意事项,常用API

  5. 把RecyclerView撸成 马 蜂 窝

  6. 深入了解RecyclerView预布局状态(preLayout)

  7. preLayout\postLayout

1、LayoutManager的作用

  1. layout(布局)子视图
  2. 滚动过程中根据子视图布局中所处的位置,决定何时添加和回收子视图
  3. 滚动子视图。

2、RecyclerView与LayoutManager的联系

  1. RV设置LayoutManager会调用requestLayout()进行View树的重绘,最终会走RV的测量、布局、绘制三大流程。
  2. RV子View的测量、布局最终都在布局阶段交由LayoutManageronLayoutChildren完成

3、LinearLayoutManager的主要方法

方法 解释
onLayoutChildren LayoutManager的主入口,在初始化布局时调用。如果Adapter数据改变或者Adapter被替换时,会再次调用。作用:初始化时放置Item,直至填满布局为止。
canScrollHorizontally() & canScrollVertically() 当想要滚动的方向,与当前布局方向相同时,在对应方法返回true,另一个返回false。
scrollHorizontallyBy() & scrollVerticallyBy() RecyclerView已经处理了触摸事件,会将相应的偏移值(dx/dy)传入这两个方法中的对应方法。根据偏移值需要完成三件事:1、将所有Item视图移动到适当位置 2、决定移动视图后 添加/移除 视图。 3、返回滚动的实际距离。框架会根据它判断你是否触碰到边界。

4、LinearLayoutManager的滚动方法源码分析。


    /**==============================================
     * RecyclerView的三种状态: 1-开始;2-布局;3-动画
     *==============================================*/
    public static class State {
    
    
        static final int STEP_START = 1;
        static final int STEP_LAYOUT = 1 << 1;
        static final int STEP_ANIMATIONS = 1 << 2;
        //xxx
    }

    /**================================================
     * 1、是否支持水平/垂直滚动
     *  1. 如果可以水平滚动,canScrollHorizontally()就返回true
     *  2. 如果可以垂直滚动,canScrollVertically()就返回true
     * @return
     *=============================================*/
    @Override
    public boolean canScrollHorizontally() {
    
    
        return mOrientation == HORIZONTAL;
    }
    @Override
    public boolean canScrollVertically() {
    
    
        return mOrientation == VERTICAL;
    }

    /**
     * 2、处理滚动事件.
     * RecyclerView处理滚动事件后,会调用对应方向的方法,并传入dx/dy偏移值。
     */
    @Override
    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
    
    
        if (mOrientation == VERTICAL) {
    
    
            return 0;
        }
        return scrollBy(dx, recycler, state);
    }
    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
    
    
        if (mOrientation == HORIZONTAL) {
    
    
            return 0;
        }
        return scrollBy(dy, recycler, state);
    }

    /**
     * 进行滑动
     */
    int scrollBy(int dy
<think>我们正在讨论RecyclerView理。用户之前询问了ListView的理,现在转向RecyclerView。根据提供的引用,RecyclerView是ListView的继承者,具有更多功能和更优性能。引用[2]指出RecyclerView由三部分组成:View、Adapter和LayoutManager,其中LayoutManager负责测量和布局。引用[3]展示了RecyclerView的滚动方法,引用[4]说明了其适用场景,引用[5]详细描述了缓存机制(如RecycledViewPool)。用户要求了解RecyclerView的工作理,因此我们需要从核心组件、工作机制、缓存策略等方面进行系统分。结构规划:1.**核心组件**:基于引用[2],介绍RecyclerView的三部分结构(Adapter、LayoutManager、ItemDecoration/ItemAnimator),对比ListView突出其解耦设计。2.**工作机制**:包括数据绑定、视图创建、布局流程(测量和布局如何由LayoutManager处理)、滚动机制(引用[3]的滚动方法示例)。3.**四级缓存机制**:详细解释RecyclerView的缓存层次(Scrap、CachedViews、ViewCacheExtension、RecycledViewPool),点引用[5]中RecycledViewPool的工作流程。4.**性能优化**:简述优化策略(如引用[4]提到的复杂布局处理)。5.**与ListView对比**:简要总结差异(如缓存机制、扩展性),呼应之前回答的ListView理。6.**总结**:强调RecyclerView的模块化优势。注意事项:-使用数学公式表示缓存机制的时间复杂度(如$O(1)$)。-引用标记:在描述缓存机制时引用[5],在说明组件时引用[2],在滚动机制处引用[3]。-代码示例:展示Adapter的基本结构(可选,非必需)。-相关问题:围绕RecyclerView的扩展使用和优化生成。最终回答需严格遵循格式要求:中文、LaTeX公式、引用标记、相关问题。</think>### RecyclerView理深入解 RecyclerView是Android中用于高效展示大型数据集的现代化列表组件,其核心理围绕**模块化设计**和**四级缓存机制**构建。以下从核心组件、工作机制、缓存策略等维度系统分: --- #### 1. **核心组件与模块化设计** RecyclerView通过解耦视图管理逻辑实现高度灵活性,核心组件包括: - **Adapter**:负责数据绑定与视图创建。需写三个关键方法: ```java public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType); // 创建视图 public void onBindViewHolder(ViewHolder holder, int position); // 绑定数据 public int getItemCount(); // 返回数据总量 ``` - **LayoutManager**:**核心创新点**(与ListView本质区别)。独立控制布局排列方式,支持线性、网格、瀑布流等布局[^2]。例如滚动时通过`scrollVerticallyBy()`计算偏移量并回收/复用视图[^3]。 - **ItemAnimator**:处理项的增加/删除/移动动画。 - **ItemDecoration**:制分割线等装饰元素。 > ✅ **优势**:模块化设计使扩展性大幅提升,例如替换`LayoutManager`即可切换列表/网格布局[^4]。 --- #### 2. **四级缓存机制(性能核心)** RecyclerView通过四级缓存实现高效视图复用,显著降低内存开销: 1. **Scrap缓存**:存储**刚移出屏幕的视图**(如滚动时临时隐藏的项),可直接复用于新位置,访问时间复杂度为$O(1)$。 2. **CachedViews**:固定容量(默认2个)的视图缓存,存储**近期被移除的项**。若新数据项位置匹配缓存项,则直接复用[^5]。 3. **ViewCacheExtension**:开发者自定义缓存层(通常留空)。 4. **RecycledViewPool**:**全局共享缓存池**。当视图不满足前三级缓存条件时,按视图类型(`viewType`)分类存储[^5]。复用流程如下: ```java void addViewHolderToRecycledViewPool(ViewHolder holder) { int viewType = holder.getItemViewType(); ArrayList<ViewHolder> scrapHeap = mScrap.get(viewType); // 按类型获取缓存列表 if (scrapHeap.size() < DEFAULT_MAX_SCRAP) { scrapHeap.add(holder); // 未满则存入 } } ``` - **数学表示**:缓存命中率提升使整体时间复杂度优化至$O(\log n)$($n$为数据量)。 --- #### 3. **完整工作流程** 1. **初始化**: - `LayoutManager`计算布局尺寸(调用`onMeasure()`和`onLayout()`)。 - `Adapter`创建当前屏幕可见项的视图(`onCreateViewHolder`)并绑定数据(`onBindViewHolder`)。 2. **滚动处理**: - 用户滚动时触发`scrollVerticallyBy()`,计算滚动距离`dy`[^3]。 - 移出屏幕的视图按优先级存入四级缓存。 - 新进入屏幕的数据项优先从缓存中获取视图(未命中则创建新视图)。 3. **数据更新**: - 使用`DiffUtil`智能计算数据差异(如`notifyItemChanged()`局部更新),避免所有项。 --- #### 4. **性能优化策略** - **视图类型分组**:不同`viewType`的视图隔离存储,减少缓存查找时间[^5]。 - **预加载**:`LayoutManager.setInitialPrefetchItemCount()`提前加载屏幕外项(适用于横向列表)。 - **固定尺寸**:设置`setHasFixedSize(true)`避免复测量。 - **嵌套优化**:复用`RecycledViewPool`解决嵌套列表性能问题[^4]。 --- #### 5. **与ListView核心差异** | **特性** | ListView | RecyclerView | |------------------|-----------------------------|-------------------------------| | **布局控制** | 仅支持垂直列表 | 解耦设计,自由扩展布局[^2] | | **缓存机制** | 两级缓存(Active/Scrap) | 四级缓存,支持全局共享池[^5] | | **动画支持** | 需手动实现 | 内置`ItemAnimator`系统 | | **更新效率** | `notifyDataSetChanged()` | 支持局部更新(`DiffUtil`) | **总结**:RecyclerView通过模块化设计(尤其是LayoutManager)和四级缓存机制,在性能、扩展性、动画支持等方面全面优于ListView,适用于列表/网格/瀑布流等复杂场景[^4][^5]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值