Android深入学习之requestLayout、invalidate和postInvalidate的区别

         Android开发离不开界面的重绘和更新,尤其是自定义控件更是经常遇到重绘更新界面的场景,下面具体介绍一下重绘界面几个方法的区别:

        (1)、requestLayout:当view确定自身已经不再适合现有的区域时,该view本身调用requestLayout这个方法要求parent view重新调用它的onMeasure、onLayout来重新计算view大小以及设置view的位置。特别的当view的layout parameter发生改变,并且它的值还没能应用到view上,这时候适合调用这个方法。(在requestLayout方法中,首先先判断当前View树是否正在布局流程,接着为当前子View设置标记位,该标记位的作用就是标记了当前的View是需要进行重新布局的,接着调用mParent.requestLayout方法,这个十分重要,因为这里是向父容器请求布局,即调用父容器的requestLayout方法,为父容器添加PFLAG_FORCE_LAYOUT标记位,而父容器又会调用它的父容器的requestLayout方法,即requestLayout事件层层向上传递,直到DecorView,即根View,而根View又会传递给ViewRootImpl,也即是说子View的requestLayout事件,最终会被ViewRootImpl接收并得到处理。)该方法必须是在UI线程中进行工作;
  (2)、invalidate:View本身调用迫使view重画,该方法常用于内部调用(比如setVisiblity())或者需要刷新界面的时候,必须是在UI线程中进行工作;该方法最后调用的也是scheduleTraversals方法,触发View的工作流程,但由于没有添加measure和layout的标记位,因此measure、layout流程不会执行,而是直接从draw流程开始;
  (3)、postInvalidate:这个方法与invalidate方法的作用是一样的,都是使View树重绘,但两者的使用条件不同,postInvalidate是在非UI线程中调用,invalidate则是在UI线程中调用。如果既要继承View而且要不希望堵塞主UI线程的话,可以另外新建线程,然后在非主UI线程中执行postInvalidate()方法去更新屏幕。

猜你喜欢

转载自blog.csdn.net/Alexlee1986/article/details/82740854