13.RecyclerView

一、什么是RecyclerView

RecyclerView介绍

有限的屏幕显示大量数据灵活的View

ListView的局限
  • 只有纵向列表一种布局
  • 没有支持动画的Api,动画实现复杂
  • 接口设计和系统不一致?
    • setOnItemClickListener
    • setOnItemLongClickListener
    • setSelection()
  • 没有强制实现ViewHolder
  • 性能不如RecyclerView
RecyclerView的优势
  • 默认支持Linear、Grid、StaggeredGrid三种布局,并每个布局支持横竖两个方向

    并支持扩展布局类型

  • 友好的ItemAnimator 动画Api

    调用noticeItemXXX 就显示默认的动画

  • 强制实现 ViewHolder

  • 解耦的架构设计
    每个类的职责分明

  • 相比ListView有更好的性能

ViewHolder 究竟是什么

viewHolder是保存View引用的容器类

  1. ViewHolder与ItemView一一对应

  2. ViewHolder解决了重复FindViewById的问题

    FindViewById有多耗性能?

  3. ViewHolder和ItemView的复用没有关系

RecyclerView的缓存原理
  • listView缓存原理

    在这里插入图片描述
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rB0b3TCm-1590326589604)(F:\Markdown\hencoder\13.RecyclerView.assets\image-20200418142731110.png)]

  • RecyclerView缓存

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-51fVd4BV-1590326589606)(F:\Markdown\hencoder\13.RecyclerView.assets\image-20200418142755383.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NuaXPPTK-1590326589609)(F:\Markdown\hencoder\13.RecyclerView.assets\image-20200418143053551.png)]

    显示区的View为Scrap,此类型的缓存会直接使用,刚移除的item放到Cache,一般上下各两个,这种类型的缓存也可以直接使用,不会调用onBindViewHolder,RecyclerViewPool里的缓存是脏了的,当复用时需要调用onBindViewHolder重新绑定数据

RecyclerView优化策略
  1. setOnItemClickListener设置在onBindViewHolder会导致重复创建,可以写在onCreateViewHolder里

  2. LinearLayoutManager.setInitialPrefetChildItemCount()?

    当用户滑动到横向滑动的ItemRecyclerView的时候,由于创建更复杂的RecyclerView以及多个子View,可能会导致页面卡顿。

    RenderThread的存在,RecyclerView会进行prefetch

    LinearLayoutManager.setInitialPrefetchItemCount(横向列表初次显示时可见的item个数)

    • 只有linearLayoutManager有这个Api
    • 只有嵌套在内部的RecyclerView才会生效
  3. RecyclerView.setHasFixedSize()

    由于RecyclerView的内容改变会导致requestLayout请求View重绘,而setHasFixedSize则只会调用layoutChildren(),跳过view的measure流程,这样可以节省一部分性能,所以如果Adapter的数据变化不会导致RecyclerView的大小变化则设置这个方法可以优化性能

  4. 多个RecyclerView共享RecyclerViewPool

  5. DiffUtil

    适用于整个页面需要刷新,但是有部分数据可能相同的情况

    new DiffUtil.Callback() {
    
            @Override
            public int getOldListSize() {
                //旧数据源大小
                return 0;
            }
    
            @Override
            public int getNewListSize() {
                //新数据源大小
                return 0;
            }
    
            @Override
            public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
                //两个对象是否应该是同一个Item
                return false;
            }
    
            @Override
            public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
                //两个对象的同一个Item是否内容改变了
                return false;
            }
    
            @Nullable
            @Override
            public Object getChangePayload(int oldItemPosition, int newItemPosition) {
                //Item局部更新,只某个属性变了
                return super.getChangePayload(oldItemPosition, newItemPosition);
            }
        };
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值