RecyclerView setHasFixedSize(true)的意义

2019-05-21 12:35:54

参考地址 RecyclerView setHasFixedSize(true)的意义


    /**

     * RecyclerView can perform several optimizations if it can know in advance that RecyclerView's

     * size is not affected by the adapter contents. RecyclerView can still change its size based

     * on other factors (e.g. its parent's size) but this size calculation cannot depend on the

     * size of its children or contents of its adapter (except the number of items in the adapter).

     * <p>

     * If your use of RecyclerView falls into this category, set this to {@code true}. It will allow

     * RecyclerView to avoid invalidating the whole layout when its adapter contents change.

     *

     * @param hasFixedSize true if adapter changes cannot affect the size of the RecyclerView.

     */

    public void setHasFixedSize(boolean hasFixedSize) {

        mHasFixedSize = hasFixedSize;

    }

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


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




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


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


   void triggerUpdateProcessor() {

            if (POST_UPDATES_ON_ANIMATION && mHasFixedSize && mIsAttached) {

                ViewCompat.postOnAnimation(RecyclerView.this, mUpdateChildViewsRunnable);

            } else {

                mAdapterUpdateDuringMeasure = true;

                requestLayout();

            }

        }


看一下triggerUpdateProcessor方法被哪些调用

onItemRangeChanged(),


onItemRangeInserted(),


onItemRangeRemoved(),


onItemRangeMoved()


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


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



        @Override

        public void onChanged() {

            assertNotInLayoutOrScroll(null);

            mState.mStructureChanged = true;

 

            setDataSetChangedAfterLayout();

            if (!mAdapterHelper.hasPendingUpdates()) {

                requestLayout();

            }

        }


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


        public final void notifyItemChanged(int position) {

            mObservable.notifyItemRangeChanged(position, 1);

        }

 

        public final void notifyItemChanged(int position, Object payload) {

            mObservable.notifyItemRangeChanged(position, 1, payload);

        }

 

        public final void notifyItemRangeChanged(int positionStart, int itemCount) {

            mObservable.notifyItemRangeChanged(positionStart, itemCount);

        }

 

        public final void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) {

            mObservable.notifyItemRangeChanged(positionStart, itemCount, payload);

        }

 

        

        public final void notifyItemInserted(int position) {

            mObservable.notifyItemRangeInserted(position, 1);

        }

 

        

        public final void notifyItemMoved(int fromPosition, int toPosition) {

            mObservable.notifyItemMoved(fromPosition, toPosition);

        }

 

        public final void notifyItemRangeInserted(int positionStart, int itemCount) {

            mObservable.notifyItemRangeInserted(positionStart, itemCount);

        }

 

        public final void notifyItemRemoved(int position) {

            mObservable.notifyItemRangeRemoved(position, 1);

        }

 

        public final void notifyItemRangeRemoved(int positionStart, int itemCount) {

            mObservable.notifyItemRangeRemoved(positionStart, itemCount);

        }




  • 2019-08-13 08:56:46

    nuxtjs组合element

    添加elementUI 插件,plugins->ele.js,代码如下

  • 2019-08-13 20:06:42

    修改 Nginx 进程最大可打开文件数(worker_processes和worker_connections)

    worker_processes:操作系统启动多少个工作进程运行Nginx。注意是工作进程,不是有多少个nginx工程。在Nginx运行的时候,会启动两种进程,一种是主进程master process;一种是工作进程worker process。例如我在配置文件中将worker_processes设置为4,启动Nginx后,使用进程查看命令观察名字叫做nginx的进程信息,我会看到如下结果:

  • 2019-08-14 09:01:18

    linux下高并发服务器实现

    在做网络服务的时候tcp并发服务端程序的编写必不可少。tcp并发通常有几种固定的设计模式套路,他们各有优点,也各有应用之处。下面就简单的讨论下这几种模式的差异:

  • 2019-08-14 13:18:59

    Linux系统下CPU使用(load average)梳理

    在平时的运维工作中,当一台服务器的性能出现问题时,通常会去看当前的CPU使用情况,尤其是看下CPU的负载情况(load average)。对一般的系统来说,根据cpu数量去判断。比如有2颗cup的机器。如果平均负载始终在1.2以下,那么基本不会出现cpu不够用的情况。也就是Load平均要小于Cpu的数量。

  • 2019-08-14 14:27:35

    计算密集型和IO密集型

    在进行I/O操作的时候,是将任务交给DMA来处理,请求发出后CPU就不管了,在DMA处理完后通过中断通知CPU处理完成了。I/O操作消耗的cpu时间很少.

  • 2019-08-14 14:29:12

    浅谈nodejs和php

    现在,Web开发公司和开发人员可以选择多种技术栈来构建Web应用程序。早期网络发展,不同的技术被用于前端和后端开发。但是,随着Node.js的发布,布局发生了变化,因为它允许开发人员使用 JavaScript 编写后端代码。这最终催生了MEAN(MongoDB + Express +AngularJS + NodeJS )堆栈 web 开发框架,从前端到后端甚至是数据库(MongoDB -JSON)都使用 JavaScript。在 Node.js 之前,Web 开发通常是在 PHP 的帮助下完成的,因为它很容易与 HTML 集成,帮助开发人员立即构建动态网站。在这篇文章中,我们将比较 Node.js 和 PHP,看哪一个最适合当前的行业需求。

  • 2019-08-15 13:32:18

    Node.js是如何解决服务器高性能瓶颈问题的

    在Java、PHP或者.net等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约2MB内存。也就是说,理论上,一个8GB内存的服务器可以同时连接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就需要增加服务器的数量,而Web应用程序的硬件成本当然就上升了。