• 面试:recyclerview的优化


    RecyclerView性能优化分析 - 掘金

    RecyclerView性能优化及高级使用_潇潇凤儿的博客-CSDN博客_recyclerview优化方案

    1、数据优化

    1. 分页加载远端数据,对拉取的远端数据进行缓存,提高二次加载速度;
    2. 对于新增或删除数据通过 DiffUtil,来进行局部数据刷新,而不是一味的全局刷新数据。

    DiffUtil是support包下新增的一个工具类,用来判断新数据和旧数据的差别,从而进行局部刷新。DiffUtil的使用,在原来调用 mAdapter.notifyDataSetChanged()的地方:

    1. // mAdapter.notifyDataSetChanged()
    2. DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffCallBack(oldDatas, newDatas), true);
    3. diffResult.dispatchUpdatesTo(mAdapter);

    2、布局优化,减少过度绘制

    减少布局层级,可以考虑使用自定义View来减少层级,或者更合理的设置布局来减少层级。

    3、减少View对象的创建

    onCreateViewHolder 和 onBindViewHolder 对时间都比较敏感,尽量避免繁琐的操作和循环创建对象。例如创建 OnClickListener,可以全局创建一个。同时onBindViewHolder调用次数会多于onCreateViewHolder的次数,如从RecyclerViewPool缓存池中取到的View都需要重新bindView,所以我们可以把监听放到CreateView中进行。

    一个稍微复杂的 Item 会包含大量的 View,而大量的 View 的创建也会消耗大量时间,所以要尽可能简化 ItemView;设计 ItemType 时,对多 ViewType 能够共用的部分尽量设计成自定义 View,减少 View 的构造和嵌套。

    4、设置高度固定

    如果item高度是固定的话,可以使用 RecyclerView.setHasFixedSize(true);来避免requestLayout浪费资源。

    5、优化滑动操作

    设置 RecyclerView.addOnScrollListener();来在滑动过程中停止加载的操作。

    6、RecyclerView缓存

    6.1 setItemViewCacheSize( int )
    RecyclerView可以设置自己所需要的ViewHolder缓存数量,默认大小是2。cacheViews中的缓存只能position相同才可得用,且不会重新bindView,CacheViews满了后移除到RecyclerPool中,并重置ViewHolder,如果对于可能来回滑动的RecyclerView,把CacheViews的缓存数量设置大一些,可以减少bindView的时间,加快布局显示。

    注:此方法是拿空间换时间,要充分考虑应用内存问题,根据应用实际使用情况设置大小。

    网上大部分设置CacheView大小时都会带上:

    setDrawingCacheEnabled(true)和setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH)

    setDrawingCacheEnabled这个是View本身的方法,意途是开启缓存。通过setDrawingCacheEnabled把cache打开,再调用getDrawingCache就可以获得view的cache图片,如果cache没有建立,系统会自动调用buildDrawingCache方法来生成cache。一般截图会用到,这里的设置drawingcache,可能是在重绘时不需要重新计算bitmap的宽高等,能加快dispatchDraw的速度,但开启drawingcache,肯定也会耗应用的内存,所以也慎用。

    6.2 复用RecycledViewPool
    在TabLayout+ViewPager+RecyclerView的场景中,当多个RecyclerView有相同的item布局结构时,多个RecyclerView共用一个RecycledViewPool可以避免创建ViewHolder的开销,避免GC。RecycledViewPool对象可通过RecyclerView对象获取,也可以自己实现。

    RecycledViewPool mPool = mRecyclerView1.getRecycledViewPool();
    下一个RecyclerView可直接进行setRecycledViewPool

    mRecyclerView2.setRecycledViewPool(mPool);

    mRecyclerView3.setRecycledViewPool(mPool);

    注意:

    (1)RecycledViewPool是依据ItemViewType来索引ViewHolder的,必须确保共享的RecyclerView的Adapter是同一个,或view type 是不会冲突的。

    (2)RecycledViewPool可以自主控制需要缓存的ViewHolder数量,每种type的默认容量是5,可通过setMaxRecycledViews来设置大小。mPool.setMaxRecycledViews(itemViewType, number); 但这会增大应用内存开销,所以也需要根据应用具体情况来使用。

    (3)利用此特性一般建议设置layout.setRecycleChildrenOnDetach(true);此属性是用来告诉LayoutManager从RecyclerView分离时,是否要回收所有的item,如果项目中复用RecycledViewPool时,开启该功能会更好的实现复用。其他RecyclerView可以复用这些回收的item。

    什么时候LayoutManager会从RecyclerView上分离呢,有两种情况:1)重新setLayoutManager()时,比如淘宝页面查看商品列表,可以线性查看,也可以表格形式查看,2)还有一种是RecyclerView从视图树上被remove时。但第一种情况,RecyclerView内部做了回收工作,设不设置影响不大,设置此属性作用主要针对第二种情况。

  • 相关阅读:
    JSON对象、字符串之间的相互转换
    Debezium系列之:基于debezium offset拉取历史数据,确保数据没有丢失
    另一种降维算法:UMAP(主要是和t-SNE进行对比)
    [mit6.s081] 笔记 Lab1: Unix utilities | Unix 实用工具
    redis数据类型及常用命令
    C++虚函数表、地址详解(x86/x64)
    已加密的PDF怎么解密?只要学会这两招即可轻松解密
    【面试高高手】—— Redis
    什么是REACH测试?
    网络代理技术与安全防护
  • 原文地址:https://blog.csdn.net/cpcpcp123/article/details/127903318