前面学习的内容:
Android自定义View(一) – 初识
Android自定义View(二) – Paint详解
Android自定义View(三) – drawText()
Android自定义View(四) – Canvas
今天继续学习Android自定义View第五篇内容绘制顺序。
本文计划根据HenCoder系列文章进行学习,所以代码风格及博文素材可能会摘自其中。
简介
前面几期讲的是「术」,是「用哪些 API 可以绘制什么内容」。到上一期为止,「术」已经讲完了,接下来要讲的是「道」,是「怎么去安排这些绘制」。
这期是「道」的第一期:绘制顺序。
Android 里面的绘制都是按顺序的,先绘制的内容会被后绘制的盖住。比如你在重叠的位置先画圆再画方,和先画方再画圆所呈现出来的结果肯定是不同的:
而在实际的项目中,绘制内容相互遮盖的情况是很普遍的,那么怎么实现自己需要的遮盖关系,就是这期要讲的内容。
1 super.onDraw() 前 or 后?
前几期我写的自定义绘制,全都是直接继承 View 类,然后重写它的 onDraw() 方法,把绘制代码写在里面,就像这样:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制代码
}
这是自定义绘制最基本的形态:继承 View 类,在 onDraw() 中完全自定义它的绘制。
之前的示例中,我把绘制代码全都写在了 super.onDraw() 的下面。其实,绘制代码写在 super.onDraw() 的上面还是下面都无所谓,甚至,你把 super.onDraw() 这行代码删掉都没关系,效果都是一样的——因为在 View 这个类里,onDraw() 本来就是空实现:
/**
* Implement this to do your drawing.
*
* @param canvas the canvas on which the background will be drawn
*/
protected void onDraw(Canvas canvas) {
}
那肯定有小伙伴要问了,既然 写在super.onDraw()的上还是下面都无所谓,你还讲个甚。
慢着慢着。。。
实际开发中,除了继承View外,更常见的是继承某个控件,重写onDraw()方法,在里面绘制代码,做出【进化版】控件
基于 EditText,在它的基础上增加了顶部的 Hint Text 和底部的字符计数。
而这种基于已有控件的自定义绘制,就不能不考虑 super.onDraw() 了:你需要根据自己的需求,判断出你绘制的内容需要盖住控件原有的内容还是需要被控件原有的内容盖住,从而确定你的绘制代码是应该写在 super.onDraw() 的上面还是下面。
1.1 写在 super.onDraw() 的下面
把绘制代码写在 super.onDraw() 的下面,由于绘制代码会在原有内容绘制结束之后才执行,所以绘制内容就会盖住控件原来的内容。
这是最为常见的情况:为控件增加点缀性内容。例如,在ImageView上方绘制尺寸
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
canvas.drawText("width:" + String.valueOf(width),100,100,paint);
canvas.drawText("height:" + String.valueOf(height),100,200,paint);
}
当然,除此之外还有其他的很多用法,具体怎么用就取决于你的需求、经验和想象力了。
1.2 写在 super.onDraw() 的上面
如果把绘制代码写在 super.onDraw()
的上面,由于绘制代码会执行在原有内容的绘制之前,所以绘制的内容会被控件的原内容盖住。
相对来说,这种用法的场景就会少一些。不过只是少一些而不是没有,比如你可以通过在文字的下层绘制纯色矩形来作为「强调色」:
public class PracticeTextView