Android 自定义 View 的绘制顺序

学习来源扔物线大神

自定义 View 各个方法的绘制顺序

  1. 先执行构造方法
  2. onFinishInflate():所有的子控件均被映射成 xml 后触发
  3. onMeasure():View放置到父容器时调用,用于测量 View 的大小
  4. onSizeChanged():在控件大小发生改变时调用。用于获取控件的宽和高度
  5. onDraw(): 绘制图形界面

继承自 View

super.onDraw() 前 or 后的区别

继承自 View 在super.onDraw()前后是没有区别的,因为在 View 这个类里,onDraw() 是空实现。

继承自特定 View

基于已有控件的自定义绘制,就需要考虑super.onDraw()的顺序了

super.onDraw() 前 or 后的区别

  • 在前

绘制代码会执行在原有内容的绘制之前,所以绘制的内容会被控件的原内容盖住。

使用场景:比如你可以通过在文字的下层绘制纯色矩形来作为「强调色」

  • 在后

绘制代码会在原有内容绘制结束之后才执行,所以绘制内容就会盖住控件原来的内容。

继承自 ViewGroup

ViewGroup 的绘制顺序:每一个 ViewGroup 会先调用自己的 onDraw()来绘制完自己的主体之后再去绘制它的子 View。这里的绘制子 View 是通过dispatchDraw()去绘制。ViewViewGroup 都有 dispatchDraw() 方法,不过由于 View 是没有子 View 的,所以一般来说 dispatchDraw() 这个方法只对 ViewGroup(以及它的子类)有意义。

super.onDraw() 前 or 后的区别

  • 在前

绘制代码会执行在原有内容的绘制之前,如果有子 view ,子 View 会遮住之前绘制的内容。

  • 在后

重写 dispatchDraw(),并在 super.dispatchDraw() 的下面写上你的绘制代码,这段绘制代码就会发生在子 View 的绘制之后,从而让绘制内容盖住子 View 了。

super.dispatchDraw() 前 or 后的区别

super.onDraw()

完整的绘制过程会依次绘制一下几个内容

  1. 背景( drawBackground() ),这个方法是 private 的,不能重写,你如果要设置背景,只能用自带的 API 去设置
  2. 主体(onDraw()
  3. 子 View(dispatchDraw()
  4. 滑动边缘渐变和滑动条(4、5 步在这个方法中实现 onDrawForeground()
  5. 前景

例如通常一个 LinearLayout 只有背景和子 View,那么它会先绘制背景再绘制子 View;一个 ImageView 有主体,有可能会再加上一层半透明的前景作为遮罩,那么它的前景也会在主体之后进行绘制

  • onDrawForeground()

onDrawForeground() 中,会依次绘制滑动边缘渐变、滑动条和前景。这个方法是 API 23 才引入的,所以在重写这个方法的时候要确认你的 minSdk 达到了 23,不然低版本的手机装上你的软件会没有效果

onDrawForeground() 前 or 后的区别

  • 在前

如果你把绘制代码写在了 super.onDrawForeground() 的下面,绘制代码会在滑动边缘渐变、滑动条和前景之后被执行,那么绘制内容将会盖住滑动边缘渐变、滑动条和前景。例如:绘制 View 的前景色

  • 在后

绘制内容都会盖住子 View,但被滑动边缘渐变、滑动条以及前景盖住。

draw() 总调度方法

除了 onDraw() dispatchDraw()onDrawForeground() 之外,还有一个可以用来实现自定义绘制的方法: draw(),draw() 是绘制过程的总调度方法。一个 View 的整个绘制过程都发生在 draw() 方法里。背景、主体、子 View 、滑动相关以及前景的绘制,它们都是在 draw() 方法中执行。

super.draw() 前 or 后的区别

  • 在前

绘制内容会被其他所有的内容盖住,包括背景

例如:给 EditText 加一个绿色的底,我们不能使用给它设置绿色背景色的方式,因为这就相当于是把它的背景替换掉,从而会导致下面的那条横线消失。这时候,我们可以重写它的 draw() 方法,然后在 super.draw() 的上方插入代码canvas.drawColor(Color.parseColor("#66BB6A")); // 涂上绿色即可完成

  • 在后

它的绘制内容会盖住其他的所有绘制内容

###

小额支持我写出更好的文章~