自定义View(四):onDraw()绘图详解
1、onDraw()方法的作用
在自定义View中,onDraw()过程是最后一步也是最难掌握的一步,因为其涉及方法之多和写法之灵活实在令人难以捉摸,他的主要作用是“画图”,现在我们来以一个简单的例子示范一下View是如何绘图的。
2、重写onDraw()方法
新建一个MyView类继承View并实现其四个构造方法,我们先看看onDraw()方法
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); }
可以看到onDraw()方法中有一个参数canvas,这个canvas就是画板,自定义View就是在画板上作画,关于Canvas类的众多画图方法请看官方文档 Canvas Api,这里我们只讲几个简单的例子。
首先我们尝试在canvas上面画一个矩形canvas.drawRect()
drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)很显然前面四个参数分别代表矩形的左、上、右、下坐标,而最后一个参数Paint则为“画笔”的意思,关于Paint的更多方法请查阅官方文档Paint Api,所以我们要先定义一个画笔。
Paint paint_g=new Paint(); paint_g.setARGB(50,0,0xff,0);
先看看setARGB()方法
setARGB(int a, int r, int g, int b)
从字面意思我们可以 这四个参数分别是:透明度、红色、绿色、蓝色,这次我们设置的是一个透明度为50%的绿色画笔。贴上onDraw()的完整代码
@Override protected void onDraw(Canvas canvas) { Paint paint_g=new Paint(); //透明度为50的绿色画笔 paint_g.setARGB(50,0,0xff,0); //在画板上画一个铺满整个View的绿色矩形 canvas.drawRect(0,0,getWidth(),getHeight(),paint_g); }
运行结果如下:
好的,我们再在这个矩形上面画一个圆试试看
@Override protected void onDraw(Canvas canvas) { Paint paint_g=new Paint(); //透明度为50的绿色画笔 paint_g.setARGB(50,0,0xff,0); //在画板上画一个铺满整个View的绿色矩形 canvas.drawRect(0,0,getWidth(),getHeight(),paint_g); Paint paint_r=new Paint(); //透明度为50的红色画笔 paint_r.setARGB(50,0xff,0,0); //在画板上画一个圆心在View中间,半径为View宽度四分之一的红色圆
//第一个参数是圆心的x坐标,第二个参数是圆心的y坐标,第三个参数是半径,第四个参数是画笔 canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/4,paint_r); }
运行结果如下
自定义View就是这样一个一个图形画上去最终达到自己想要的效果。
3、尝试动态画图
我们再重写onTouchEvent方法,如下
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: touch_x=event.getX(); touch_y=event.getY(); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_x=event.getX(); touch_y=event.getY(); invalidate();//重绘视图 break; case MotionEvent.ACTION_UP: touch_x=0; touch_y=0; invalidate();//重绘视图 break; } return true; } @Override protected void onDraw(Canvas canvas) { Paint paint_g=new Paint(); //透明度为50的绿色画笔 paint_g.setARGB(50,0,0xff,0); //在画板上画一个铺满整个View的绿色矩形 canvas.drawRect(0,0,getWidth(),getHeight(),paint_g); if (touch_x!=0&touch_y!=0){ Paint paint_r=new Paint(); paint_r.setARGB(50,0xff,0,0); canvas.drawCircle(touch_x,touch_y,getWidth()/4,paint_r); } }
touch_x和touch_y是MyView的两个成员变量,用来记录触摸的点,在onDraw方法中,以触摸点为圆心绘圆,当两点都为0的时候则不绘圆形。
运行效果:
从效果图中可以看到当触摸时就会显示圆,并会跟着触摸点移动。上完整代码:
public class MyView extends View { private float touch_x=0,touch_y=0; private Canvas canvas; public MyView(Context context) { super(context); } public MyView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: touch_x=event.getX(); touch_y=event.getY(); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_x=event.getX(); touch_y=event.getY(); invalidate(); break; case MotionEvent.ACTION_UP: touch_x=0; touch_y=0; postInvalidate(); break; } return true; } @Override protected void onDraw(Canvas canvas) { Paint paint_g=new Paint(); //透明度为50的绿色画笔 paint_g.setARGB(50,0,0xff,0); //在画板上画一个铺满整个View的绿色矩形 canvas.drawRect(0,0,getWidth(),getHeight(),paint_g); if (touch_x!=0&touch_y!=0){ Paint paint_r=new Paint(); paint_r.setARGB(50,0xff,0,0); canvas.drawCircle(touch_x,touch_y,getWidth()/4,paint_r); } } }
4、源码链接
https://github.com/Hasagit/DrawDemo.git