自定义 View 绘制顺序 HenCoder-5 [MD]
2021-05-29 11:03
标签:mon 触摸 and 项目 使用 private 好的 col 目标 博文地址 全文整理自 扔物线(HenCoder)自定义 View 系列文章 重新整理的目标: 扔物线自定义 View 系列教程分 Android 里面的绘制都是按顺序的,先绘制的内容会被后绘制的 一个完整的绘制过程会依次绘制以下几个内容: 这个方法是 绘制内容就会盖住控件原来的内容,可以为控件增加点缀性内容。 在 Debug 模式下绘制出 ImageView 的图像尺寸信息: 绘制的内容会被控件的原内容盖住,这种用法的场景相对来说会少一些。 通过在文字的下层绘制纯色矩形来作为「强调色」: 在绘制过程中,每个 View 和 ViewGroup 都会先调用 如果你继承了一个 注:由于 View 没有子 View,所以一般来说这个方法只对 绘制的内容发生在子 View 的绘制之后,所以 上面说的 这其实和前面讲的把绘制代码写在 虽然这三部分是依次绘制的,但它们被一起写进了这个方法里,所以不能在它们之间插入自定义绘制 绘制代码会在滑动边缘渐变、滑动条和前景之后被执行,所以绘制内容会 在 ImageView 左上角添加「New」标签,要求不能被遮罩(foreground)盖住 这种写法,和前面讲的把绘制代码写在 在 ImageView 左上角添加「New」标签,要求需要被遮罩(foreground)盖住 所以也可以通过重写 绘制的内容会在其他所有绘制完成之后再执行,也就是说,它的绘制内容会 它的效果和把绘制代码写在 绘制的内容会在其他所有绘制之前被执行,所以这部分绘制内容会被其他所有的内容盖住,包括背景。 是不是觉得没用?觉得怎么可能会有谁想要在背景的下面绘制内容?别这么想,有的时候它还真的有用。 例如 如果我想给这个 在这种时候,你就可以重写它的 关于绘制方法,有两点需要注意: 1、在 出于效率的考虑, 2、在重写的方法有多个选择时,优先选择 一般情况,一段绘制代码写在不同的绘制方法中效果是一样的,但有一个例外:如果绘制代码既可以写在 2021-5-7 自定义 View 绘制顺序 HenCoder-5 [MD] 标签:mon 触摸 and 项目 使用 private 好的 col 目标 原文地址:https://www.cnblogs.com/baiqiantao/p/14743101.html
我的GitHub
我的博客
我的微信
我的邮箱
baiqiantao
baiqiantao
bqt20094
baiqiantao@sina.com
目录
扔物线自定义 View 系列教程总结-5
绘制
、布局
和触摸反馈
三部分内容。绘制顺序
总结
盖住
,所以控制好绘制顺序是非常重要的。
drawBackground()
onDraw()
dispatchDraw()
onDrawForeground()
drawBackground 绘制背景
private
的,不能重写,也就是说不能自定义绘制。可以通过android:background
属性或View.setBackgroundXxx()
方法设置背景。onDraw 绘制主体
onDraw()
是负责自身主体内容
绘制的。在 View
中,onDraw()
是空实现,所以直接继承 View 的类,它们的 super.onDraw()
什么也不会做。写在 super.onDraw 下面
写在 super.onDraw 上面
dispatchDraw 绘制子 View
onDraw()
方法来绘制主体,再调用 dispatchDraw()
方法来绘制子 View。LinearLayout
,重写了它的 onDraw()
方法,在 super.onDraw()
后插入了你自己的绘制代码,以便使它能够在内部绘制一些斑点作为点缀。但是你会发现,当你添加了子 View 之后,你的斑点不见了。造成这种情况的原因是:在绘制过程中,每一个 ViewGroup 会先调用自己的 onDraw()
来绘制完自己的主体之后再去绘制它的子 View,那么在子 View 绘制完成之后,先前绘制的斑点就被子 View 盖住了。
ViewGroup
有意义。写在 super.dispatchDraw 下面
绘制内容会盖住子 View
。
LinearLayout
案例,就应该放在 super.dispatchDraw
下面写在 super.dispatchDraw 上面
super.onDraw()
之后的效果是一样的。onDrawForeground 绘制前景
Android 6.0(API 23)
之前,仅FrameLayout
支持前景,6.0 后所有View
都支持android:scrollbarXXX
系列属性或View.setXXXScrollbarXXX()
系列方法来设置android:foreground
属性或View.setForeground()
方法来设置
写在 super.onDrawForeground 下面
盖住滑动边缘渐变、滑动条和前景
。
写在 super.onDrawForeground 上面
super.dispatchDraw()
的下面的效果是一样的。
draw 总调度方法
draw()
是绘制过程的总调度方法
,一个 View 的整个绘制过程都发生在 draw()
方法里。前面讲到的背景、主体、子 View 、滑动相关以及前景的绘制,它们其实都是在 draw()
方法里调用的。// View.java 的 draw() 方法的简化版大致结构
public void draw(Canvas canvas) {
drawBackground(Canvas); // 绘制背景(不能重写)
onDraw(Canvas); // 绘制主体
dispatchDraw(Canvas); // 绘制子 View
onDrawForeground(Canvas); // 绘制滑动相关和前景
}
draw()
方法来做自定义的绘制。写在 super.draw 下面
盖住其他的所有绘制内容
。super.onDrawForeground()
下面时的效果是一样的,都会盖住其他的所有内容。写在 super.draw 上面
EditText
,它下面的那条横线是它的背景(background
)EditText
加一个绿色的底,我不能使用给它设置绿色背景色android:background="#66BB6A"
的方式,因为这就相当于是把它的背景替换掉,从而会导致下面的那条横线消失draw()
方法,然后在 super.draw()
的上方插入代码,以此来在所有内容的底部涂上一片绿色:public void draw(Canvas canvas) {
canvas.drawColor(Color.parseColor("#66BB6A")); // 涂上绿色
super.draw(canvas);
}
注意事项
ViewGroup
的子类中重写除 dispatchDraw()
以外的绘制方法时,可能需要调用 setWillNotDraw(false)
ViewGroup
默认会绕过 draw()
方法,换而直接执行 dispatchDraw()
,以此来简化绘制流程。所以如果你自定义了某个 ViewGroup
的子类并且需要在它的除 dispatchDraw()
以外的任何一个绘制方法内绘制内容,你 可能 会需要调用 View.setWillNotDraw(false)
这行代码来切换到完整的绘制流程。是「可能」而不是「必须」的原因是,有些 ViewGroup 是已经调用过 setWillNotDraw(false)
了的,例如 ScrollView
。onDraw()
onDraw()
里,也可以写在其他绘制方法里,那么优先写在 onDraw()
。因为 Android 有相关的优化,可以在不需要重绘的时候自动跳过 onDraw()
的重复执行,以提升开发效率。享受这种优化的只有 onDraw()
一个方法。
文章标题:自定义 View 绘制顺序 HenCoder-5 [MD]
文章链接:http://soscw.com/index.php/essay/89088.html