Invalidate、postInvalidate、requestLayout应用场景与区别

1、Invalidate和postInvalidate的区别

Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。 
鉴于此,如果要使用invalidate的刷新,那我们就得配合handler的使用,使异步非ui线程转到ui线程中调用,如果要在非ui线程中直接使用就调用postInvalidate方法即可,这样就省去使用handler的烦恼。但实际上postInvalidate() 底层的实现还是通过 Hanlder 的,但是底层封装起来了,让我们直接可以在子线程调用

2、Invalidate和requestLayout在什么时候用呢?

当view确定自身已经不再适合现有的区域时,该view本身调用这个方法要求parent view(父类的视图)重新调用他的onMeasure、onLayout来重新设置自己位置。特别是当view的layoutparameter发生改变,并且它的值还没能应用到view上时,这时候适合调用这个方法。 
Invalidate调用onDraw方法,requestLayout调用onMeasure和onLayout,不一定调用onDraw

一般来说,如果View确定自身不再适合当前区域,比如说它的LayoutParams发生了改变,需要父布局对其进行重新测量、布局、绘制这三个流程,往往使用requestLayout。而invalidate则是刷新当前View,使当前View进行重绘,不会进行测量、布局流程,因此如果View只需要重绘而不需要测量,布局的时候,使用invalidate方法往往比requestLayout方法更高效。

总结:

View绘制分三个步骤,顺序是:onMeasure,onLayout,onDraw。经代码亲测,log输出显示:调用invalidate方法只会执行onDraw方法;调用requestLayout方法只会执行onMeasure方法和onLayout方法,并不会执行onDraw方法。

所以当我们进行View更新时,若仅View的显示内容发生改变且新显示内容不影响View的大小、位置,则只需调用invalidate方法;若View宽高、位置发生改变且显示内容不变,只需调用requestLayout方法;若两者均发生改变,则需调用两者,按照View的绘制流程,推荐先调用requestLayout方法再调用invalidate方法。

requestLayout : 当当前布局的宽高发生改变的时候, 此时需要重新调用父view的onMeaure和onLayout, 来给子view重新排版布局
invalidate : 让页面刷新, 重新调用onDraw方法,
postInvalidate : 在子线程来让页面来进行刷新的方法

参考资料:从实例和源码角度理解 postInvalidate() 和 invalidate() 的区别与联系

                  requestLayout、invalidate与postInvalidate的区别与使用场景分析

                  Android requestLayout 和 invalidata , postInvalidate 比较

猜你喜欢

转载自blog.csdn.net/mountain_hua/article/details/81293030