一.继承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);
    }
}

效果图如下:

android view怎么绘制竖线_控件


如果将onDraw方法上面几行自定义绘制代码移到它的下面,就会出现下面的效果:

android view怎么绘制竖线_父类_02


因此在继承其他控件时一定要注意上面的绘制顺序,以免出现上面的错误。

三.主体和子View的绘制顺序

在继承其他的布局,实现自定义布局时,如果按照上面的步骤给这个自定义布局中添加自定义绘制代码,并且在xml文件中给此布局添加子VIew,你会发现你的自定义绘制代码不起作用了。这时就要提到dispatchDraw(),它是绘制子 View 的方法。

它和onDraw()的绘制顺序如下:

android view怎么绘制竖线_自定义_03


如果你想让自己的自定义图形在最上面显示,如下面的效果,就需要在重写父类dispatchDraw()方法,将自定义绘制代码移到super.dispatchDraw()方法下面.

而如果在super.dispatchDraw()方法上面绘制,就会又出现自定义绘制图形被盖住的情况.

android view怎么绘制竖线_安卓_04

public class SpottedLinearLayout extends LinearLayout {
    ...
    protected void dispatchDraw(Canvas canvas) {
       super.dispatchDraw(canvas);
       ... // 自定义绘制代码
    }
}

参考文章:
自定义View的绘制顺序