zoukankan      html  css  js  c++  java
  • RecyclerView性能优化

    1、数据处理与视图加载分离

    bindViewHolder方法是在UI线程进行的,此方法不能耗时操作,不然将会影响滑动流畅性。
    优化前:
    
    class Task {
        Date dateDue;
        String title;
        String description;
    
        // getters and setters here
    }
    
    class MyRecyclerView.Adapter extends RecyclerView.Adapter {
    
        static final TODAYS_DATE = new Date();
        static final DATE_FORMAT = new SimpleDateFormat("MM dd, yyyy");
    
        public onBindViewHolder(Task.ViewHolder tvh, int position) {
            Task task = getItem(position);
    
            if (TODAYS_DATE.compareTo(task.dateDue) > 0) {
                tvh.backgroundView.setColor(Color.GREEN);
            } else {
                tvh.backgroundView.setColor(Color.RED);
            }
    
            String dueDateFormatted = DATE_FORMAT.format(task.getDateDue());
            tvh.dateTextView.setDate(dueDateFormatted);
        }
    }
    上面的onBindViewHolder方法中进行了日期的比较和日期的格式化,这个是很耗时的,在onBindViewHolder方法中,应该只是将数据set到视图中,而不应进行业务的处理。
    优化后:
    
    public class TaskViewModel {
        int overdueColor;
        String dateDue;
      // getters and setters }
    public onBindViewHolder(Task.ViewHolder tvh, int position) { TaskViewModel taskViewModel = getItem(position); tvh.backgroundView.setColor(taskViewModel.getOverdueColor()); tvh.dateTextView.setDate(taskViewModel.getDateDue()); }

    2、数据优化

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

    DiffUtil是support包下新增的一个工具类,用来判断新数据和旧数据的差别,从而进行局部刷新。
    DiffUtil的使用,在原来调用mAdapter.notifyDataSetChanged()的地方:
    // mAdapter.notifyDataSetChanged()
    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new DiffCallBack(oldDatas, newDatas), true);
    diffResult.dispatchUpdatesTo(mAdapter);
    
    
    DiffUtil最终是调用Adapter的下面几个方法来进行局部刷新:
    mAdapter.notifyItemRangeInserted(position, count);
    mAdapter.notifyItemRangeRemoved(position, count);
    mAdapter.notifyItemMoved(fromPosition, toPosition);
    mAdapter.notifyItemRangeChanged(position, count, payload);

    3、布局优化

    减少xml文件inflate时间
    xml文件包括:layout、drawable的xml,xml文件inflate出ItemView是通过耗时的IO操作。可以使用代码去生成布局,即new View()的方式。这种方式是比较麻烦,但是在布局太过复杂,或对性能要求比较高的时候可以使用。
    减少View对象的创建
    一个稍微复杂的 Item 会包含大量的 View,而大量的 View 的创建也会消耗大量时间,所以要尽可能简化 ItemView;设计 ItemType 时,对多 ViewType 能够共用的部分尽量设计成自定义 View,减少 View 的构造和嵌套。

    4、数据Prefatch预取

    升级 RecycleView 版本到 25.1.0 (>=21)及以上使用 Prefetch 功能
    1)setItemPrefatchEnable(false)可关闭预取功能
    2)嵌套时且使用的是LinearLayoutManager,子RecyclerView可通过setInitialPrefatchItemCount设置预取个数
    3)二级缓存时不需要重新绑定

    5、加大RecyclerView缓存

    recyclerView.setItemViewCacheSize(20);
    recyclerView.setDrawingCacheEnabled(true);
    recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
    通过 RecycleView.setItemViewCacheSize(size); 来加大 RecyclerView 的缓存,用空间换时间来提高滚动的流畅性。

    6、item设置高度固定

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

    7、通过重写 RecyclerView.onViewRecycled(holder) 来回收资源

    8、对 TextView 使用 String.toUpperCase 来替代 android:textAllCaps="true"

    使用textAllCaps会导致申请更多内存,当为true时,TextView内部都会创建一个新的Transformnation来处理字符串

    9、共用RecycledViewPool

    如果多个 RecycledView 的 Adapter 是一样的,比如嵌套的 RecyclerView 中存在一样的 Adapter,可以通过设置 RecyclerView.setRecycledViewPool(pool); 来共用一个 RecycledViewPool。

    10、增加RecyclerView预留的额外空间

    额外空间:显示范围之外,应该额外缓存的空间
    new LinearLayoutManager(this) {
        @Override
        protected int getExtraLayoutSpace(RecyclerView.State state) {
            return size;
        }
    };

    11、优化滑动操作

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

    12、减少ItemView监听器的创建

    对 ItemView 设置监听器,不要对每个 Item 都调用 addXxListener,应该大家公用一个 XxListener,根据 ID 来进行不同的操作,优化了对象的频繁创建带来的资源消耗。

    13、处理刷新闪烁

    用notifyDataSetChange时,适配器不知道整个数据集中的那些内容以及存在,再重新匹配ViewHolder时会花生闪烁。
    设置adapter.setHasStableIds(true),并重写getItemId()来给每个Item一个唯一的ID
  • 相关阅读:
    Eclipse JSP/Servlet 环境搭建
    1,有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
    Electron-vue实战(二)— 请求Mock数据渲染页面
    Electron-vue实战(一)—搭建项目与安装Element UI
    Electron-vue实战(三)— 如何在Vuex中管理Mock数据
    vue学习笔记(六)— 关于Vuex可以这样简单理解
    vue学习笔记(五)— 组件通信
    OpenLayers学习笔记(十二)— 飞机速度矢量线预测(二)
    QML学习笔记(八)— QML实现列表侧滑覆盖按钮
    重学JavaScript
  • 原文地址:https://www.cnblogs.com/zgz345/p/13436005.html
Copyright © 2011-2022 走看看