一.继承View的绘制顺序
继承View时,无论在super.onDraw(canvas)方法上面还是下面自定义绘制代码时,效果都是只会绘制你的自定义绘制代码。因为View中的onDraw方法是空实现。
public class MyView extends View {
...
protected void onDraw(Canvas canvas) {
//在super.onDraw(canvas)方法上面自定义绘制代码
super.onDraw(canvas);
//在下面自定义绘制代码
}
...
}
二.继承其他已有的控件
继承其他已有的控件(如TextView,EditView等),目的是对它们原有的功能进行扩展,加入自己想要的功能。但这些控件都重写了父类的onDraw方法,因此需要留意绘制顺序的问题。
如果把绘制代码写在 super.onDraw() 的上面,由于绘制代码会执行在原有内容的绘制之前,所以绘制的内容会被控件的原内容盖住。简单来说就是先绘制的会被后面的盖住。
public class MyTextView extends TextView {
...
@Override
protected void onDraw(Canvas canvas) {
//在onDraw方法上面绘制背景
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.YELLOW);
canvas.drawRect(getLeft(), getTop(), getRight(), getBottom(), paint);
super.onDraw(canvas);
}
}
效果图如下:
如果将onDraw方法上面几行自定义绘制代码移到它的下面,就会出现下面的效果:
因此在继承其他控件时一定要注意上面的绘制顺序,以免出现上面的错误。
三.主体和子View的绘制顺序
在继承其他的布局,实现自定义布局时,如果按照上面的步骤给这个自定义布局中添加自定义绘制代码,并且在xml文件中给此布局添加子VIew,你会发现你的自定义绘制代码不起作用了。这时就要提到dispatchDraw(),它是绘制子 View 的方法。
它和onDraw()的绘制顺序如下:
如果你想让自己的自定义图形在最上面显示,如下面的效果,就需要在重写父类dispatchDraw()方法,将自定义绘制代码移到super.dispatchDraw()方法下面.
而如果在super.dispatchDraw()方法上面绘制,就会又出现自定义绘制图形被盖住的情况.
public class SpottedLinearLayout extends LinearLayout {
...
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
... // 自定义绘制代码
}
}
参考文章:
自定义View的绘制顺序