🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 描述一下View的绘制原理? View的绘制流程主要分为三步: 1. onMeasure:测量视图的大小,从顶层父View到子View递归调用measure()方法,measure()调用onMeasure()方法,onMeasure()方法完成测量工作。 2. onLayout:确定视图的位置,从顶层父View到子View递归调用layout()方法,父View将上一步measure()方法得到的子View的布局大小和布局参数,将子View放在合适的位置上。 3. onDraw:绘制最终的视图,首先ViewRoot创建一个Canvas对象,然后调用onDraw()方法进行绘制。onDraw()方法的绘制流程为: ① 绘制视图背景。 ② 绘制画布的图层。 ③ 绘制View内容。 ④ 绘制子视图,如果有的话。 ⑤ 还原图层。 ⑥ 绘制滚动条。 ### requestLayout()、invalidate()与postInvalidate()有什么区别? - requestLayout():该方法会递归调用父窗口的requestLayout()方法,直到触发ViewRootImpl的performTraversals()方法,此时mLayoutRequestede为true,会触发onMesaure()与onLayout()方法,不一定 会触发onDraw()方法。 - invalidate():该方法递归调用父View的invalidateChildInParent()方法,直到调用ViewRootImpl的invalidateChildInParent()方法,最终触发ViewRootImpl的performTraversals()方法,此时mLayoutRequestede为false,不会 触发onMesaure()与onLayout()方法,当时会触发onDraw()方法。 - postInvalidate():该方法功能和invalidate()一样,只是它可以在非UI线程中调用。 一般说来需要重新布局就调用requestLayout()方法,需要重新绘制就调用invalidate()方法。