【Android View绘制体系】invalidate

来源:互联网 发布:伊卡尔迪 国家队 知乎 编辑:程序博客网 时间:2024/05/22 04:47

invalidate内部思想

这里写图片描述
这里写图片描述
这里写图片描述

invalidate的调用流图

image

View.invalidateInternal

image

打上DIRTY标记

为后面Draw做准备

mPrivateFlags |= PFLAG_DIRTY;

调用父组件的invalidateChild

并将自身相对位置left,top,right,bottom通知给父组件

ViewGroup.invalidateChild

image

循环执行父组件的invalidateChildInParent,直到执行到ViewRootImpl完后会返回null,也就到头了。

ViewGroup.invalidateChildInParent

image

需要重绘的区域由两个数据来定义的:

  • location数组:为自身左边,上边距离父组件的距离。确立了在坐标系的相对位置
  • dirty:一个包含自身宽高的矩形面积。确立了需要重绘的面积大小

二者告知了在屏幕的具体哪个区域是需要重绘的。

ViewRootImpl.invalidateChildInParent

image

ViewRootImpl.invalidateRectOnScreen

这里写图片描述

加入重绘区域合集

 localDirty.union(dirty.left, dirty.top, dirty.right, dirty.bottom);

本次invalidate的dirty区域同之前的dirty区域合并

 final boolean intersected = localDirty.intersect(0, 0,                (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));if (!intersected) {    localDirty.setEmpty();}

判断要重绘的区域是不是在屏幕内,也就是判断dirty和屏幕区域是否有交叉,屏幕外的就不用去绘制了。

scheduleTraversals();

开始遍历绘制

invalidate()使用场景

一般引起invalidate()操作的函数如下:
1、直接调用invalidate()方法,请求重新draw(),但只会绘制调用者本身。
2、setSelection()方法 :请求重新draw(),但只会绘制调用者本身。
3、setVisibility()方法 : 当View可视状态在INVISIBLE转换VISIBLE时,会间接调用invalidate()方法,继而绘制该View。
4 、setEnabled()方法 : 请求重新draw(),但不会重新绘制任何视图包括该调用者本身。

0 0