RecyclerView setHasFixedSize(true)的意义
2017年07月07日 16:23:04

阅读数:6831
  1. <span style="font-size:18px;">    /**
  2. * RecyclerView can perform several optimizations if it can know in advance that RecyclerView's
  3. * size is not affected by the adapter contents. RecyclerView can still change its size based
  4. * on other factors (e.g. its parent's size) but this size calculation cannot depend on the
  5. * size of its children or contents of its adapter (except the number of items in the adapter).
  6. * <p>
  7. * If your use of RecyclerView falls into this category, set this to {@code true}. It will allow
  8. * RecyclerView to avoid invalidating the whole layout when its adapter contents change.
  9. *
  10. * @param hasFixedSize true if adapter changes cannot affect the size of the RecyclerView.
  11. */
  12. public void setHasFixedSize(boolean hasFixedSize) {
  13. mHasFixedSize = hasFixedSize;
  14. }</span>

注释说当知道Adapter内Item的改变不会影响RecyclerView宽高的时候,可以设置为true让RecyclerView避免重新计算大小。

设置为true,再调用notifyDataSetChanged(),发现大小重新计算了,看来理解出现错误了。还是再看一下哪些地方用到这个mHasFixedSize吧。

首先是onMeasure里用到,这个和自定义LayoutManager相关,先不管它。

剩下的就是triggerUpdateProcessor()方法了:

  1. <span style="font-size:18px;">   void triggerUpdateProcessor() {
  2. if (POST_UPDATES_ON_ANIMATION && mHasFixedSize && mIsAttached) {
  3. ViewCompat.postOnAnimation(RecyclerView.this, mUpdateChildViewsRunnable);
  4. } else {
  5. mAdapterUpdateDuringMeasure = true;
  6. requestLayout();
  7. }
  8. }</span>

看一下triggerUpdateProcessor方法被哪些调用

onItemRangeChanged(),

onItemRangeInserted(),

onItemRangeRemoved(),

onItemRangeMoved()

这样看就很明白了,当调用Adapter的增删改插方法,最后就会根据mHasFixedSize这个值来判断需要不需要requestLayout();

再来看一下notifyDataSetChanged()执行的代码,最后是调用了onChanged,调用了requestLayout(),会去重新测量宽高。

  1. @Override
  2. public void onChanged() {
  3. assertNotInLayoutOrScroll(null);
  4. mState.mStructureChanged = true;
  5. setDataSetChangedAfterLayout();
  6. if (!mAdapterHelper.hasPendingUpdates()) {
  7. requestLayout();
  8. }
  9. }

总结:当我们确定Item的改变不会影响RecyclerView的宽高的时候可以设置setHasFixedSize(true),并通过Adapter的增删改插方法去刷新RecyclerView,而不是通过notifyDataSetChanged()。(其实可以直接设置为true,当需要改变宽高的时候就用notifyDataSetChanged()去整体刷新一下)

  1. public final void notifyItemChanged(int position) {
  2. mObservable.notifyItemRangeChanged(position, 1);
  3. }
  4. public final void notifyItemChanged(int position, Object payload) {
  5. mObservable.notifyItemRangeChanged(position, 1, payload);
  6. }
  7. public final void notifyItemRangeChanged(int positionStart, int itemCount) {
  8. mObservable.notifyItemRangeChanged(positionStart, itemCount);
  9. }
  10. public final void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) {
  11. mObservable.notifyItemRangeChanged(positionStart, itemCount, payload);
  12. }
  13. public final void notifyItemInserted(int position) {
  14. mObservable.notifyItemRangeInserted(position, 1);
  15. }
  16. public final void notifyItemMoved(int fromPosition, int toPosition) {
  17. mObservable.notifyItemMoved(fromPosition, toPosition);
  18. }
  19. public final void notifyItemRangeInserted(int positionStart, int itemCount) {
  20. mObservable.notifyItemRangeInserted(positionStart, itemCount);
  21. }
  22. public final void notifyItemRemoved(int position) {
  23. mObservable.notifyItemRangeRemoved(position, 1);
  24. }
  25. public final void notifyItemRangeRemoved(int positionStart, int itemCount) {
  26. mObservable.notifyItemRangeRemoved(positionStart, itemCount);
  27. }

setHasFixedSize(true)的意义 (转)的更多相关文章

  1. [Android]使用RecyclerView替代ListView(一)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4232560.html RecyclerView是一个比List ...

  2. [转]RecyclerView初探

    原文地址:http://www.grokkingandroid.com/first-glance-androids-recyclerview/ RecyclerView是去年谷歌I/O大会上随Andr ...

  3. 【RecyclerView优化】

    1.局部刷新 (1)避免整个列表的数据更新,只更新受影响的布局.例如,加载更多时,不使用notifyDataSetChanged(),而是使用notifyItemRangeInserted(range ...

  4. DiyCode开源项目 TopicActivity 分析

    1.首先看看TopActivity效果.    2.TopicActivity是一个继承BaseActivity的.前面分析过BaseActivity了.主要有一个标题栏,有返回的图标. 3.贴一下T ...

  5. Android面试题收录及解答10月刊

    前言 嗨,大家好,好久不见.这里跟大家侃侃这中间发生了什么. 一个月前呢,想准备面试,就网上随便找找面试题什么的,发现要么就是卖课的,要么就是不给详细回答的或者回答不够深的(也许是我没找到).反正稍微 ...

  6. 用Kotlin语言重新编写Plaid APP:经验教训(I)

    原文标题:Converting Plaid to Kotlin: Lessons learned (Part 1) 原文链接:http://antonioleiva.com/plaid-kotlin- ...

  7. 组件RecyclerView的应用(一)

    首先我们知道RecyclerView组件是ListView的升级版,今天先介绍基础的RecyclerView的基本布局RecyclerView.Adapter和LayoutManager 第一: La ...

  8. [spring源码学习]四、IOC源码——普通bean初始化

    一.代码例子 此节开始涉及到一个bean具体生成和保存的过程,仅仅涉及到最简单的bean,代码依旧是最简单的 public static void main(String[] args) { Defa ...

  9. Android RecyclerView 的简单使用

    Android L SDK发布的,新API中最有意思的就是RecyclerView (后面为RV) 和 CardView了, 按照官方的说法, RV 是一个ListView 的一个更高级更灵活的一个版 ...

随机推荐

  1. 在webstorm中编译less,以及压缩css

    一.编译   在全局安装less npm install -g less 在webstorm setting ->tools -> filewatcher中设置 :  ../css/$Fi ...

  2. webpack整合 .vue 文件,集成 vue-loader

    webpack集成vue-loader 创建一个文件夹 test_webpack_vue 在 test_webpack_vue 下新建目录 src 在 src 目录下 新建文件 index.html ...

  3. mysql使用存储过程,批量生成测试数据

    1.存储过程代码 delimiter $$DROP PROCEDURE IF EXISTS create_service_data$$create procedure create_service_d ...

  4. 【异常】hue:unknown database hue

    1 hue error日志报错,找不到hue数据库 2 解决办法 删除hue服务,重新添加,再次在添加database阶段验证密码,test通过,再继续. 还有造成这个事情的原因,是自己移动了mysq ...

  5. kubernetes资源清单之pod

    什么是pod? Pod是一组一个或多个容器(例如Docker容器),具有共享的存储/网络,以及有关如何运行这些容器的规范. Pod的内容始终位于同一地点,并在同一时间安排,并在共享上下文中运行. Po ...

  6. 利用协程和socket实现并发

    服务端代码 from gevent import monkey monkey.patch_all() from gevent import spawn import socket def commun ...

  7. 基础数据 补充 set() 集合 深浅拷贝

    一  对字符串的操作 li = ["张曼玉", "朱茵", "关之琳", "刘嘉玲"] s = "_" ...

  8. 关于注解-Hebernate与JPA(java persistence api)

    The JPA spec. defines the JPA annotation in the javax.persistence package. Hibernate not only implem ...

  9. u-boot-2018.09 DTS上 I2C节点的解析 (转)

    这篇理下uboot上I2C总线挂载设备的整个流程. 其他总线(如SPI等)应是类同的思路. uboot 中,以max8997挂载到s3c24xx i2c总线为例, dts里面的写法如下 aliases ...

  10. Gym - 101955E The Kouga Ninja Scrolls (曼哈顿距离变换+线段树)

    题意:有n个忍者(编号为1-n),每个忍者有三个属性:横坐标x,纵坐标y,所属门派c,要求支持三种操作: 1.改变第k个忍者的位置 2.改变第k个忍者的门派 3.查询编号为[l,r]之间的忍者中,所属 ...