Android — 自定义View(二)之绘制基本图形

前言

回顾第一篇,我们主要讲了View的坐标系以及绘制自定义View的流程等基础知识。这篇文章主要讲用Canvas绘制一些以基本图形图形,目录如下:

  1. Canvas简介
  2. Canvas常用操作表
  3. Canvas操作详解
  4. Paint简介
  5. 实例之制作一个饼状图

那准备开始了吗?

Canvas简介

Canvas即画布,我们能够在上面绘制各种东西,是Android平台2D图形绘制的基础,非常强大。

Canvas常用操作表

操作类型 相关方法 备注
绘制颜色 drawColor()、drawRGB()、drawARGB() 使用单一颜色填充整个画布
绘制基本形状 drawPoint()、drawPoints()、drawLine()、drawLines()、drawRect()、drawRoundRect()、drawOval()、drawCircle()、drawArc() 依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧
绘制图片 drawBitmap()、drawPicture() 绘制位图和图片
绘制文本 drawText()、drawPosText()、drawTextOnPath() 依次为绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字
绘制路径 drawPath() 绘制路径,绘制贝塞尔曲线时也需要用到该函数
画布快照 save()、restore()、saveLayerXxx()、restoreToCount()、getSaveCount() 依次为保存当前状态、回滚到上一次的状态、保存图层状态、回滚到指定状态、获取保存次数
画布变换 translate()、scale()、rotate()、skew() 依次为位移、缩放、旋转、错切

Canvas常用操作详解

绘制颜色:

绘制颜色是填充整个画布,常用于绘制底色。

1
canvas.drawColor(Color.BLUE); //绘制蓝色

创建画笔:

要想绘制内容,首先要创建一个画笔,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 1.创建一个画笔
private Paint mPaint=new Paint();
// 2.初始化画笔
private void initPaint() {
mPaint.setColor(Color.RED); //设置画笔颜色
mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充
mPaint.setStrokeWidth(10f); //设置画笔宽度
}
// 3.在构造方法中调用
public PieChart(Context context) {
super(context);
initPaint();
}
public PieChart(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initPaint();
}
public PieChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
}

之后就可以在Canvas中绘制各种内容了。

绘制点:

1
2
canvas.drawPoint(100, 100, mPaint);
canvas.drawPoints(new float[]{200, 200, 200, 300, 200, 400}, mPaint);

其实知道参数是什么就明白了,参数显然是坐标点。

绘制直线:

绘制直线需要两个点,起点和终点,同上也能绘制一组直线。

1
2
canvas.drawLine(150, 150, 300, 300, mPaint);
canvas.drawLines(new float[]{50, 50, 100, 100, 50, 150, 100, 200}, mPaint);

绘制矩形:

确定一个矩形至少需要四个数据,即对角线两点的坐标值,一般是采用左上角和右下角。

关于绘制矩形,一般采用了三种重载方法,第一种就是提供四个数值,其余两种则是把矩形封装成Rect或RectF(实际上仍然是用两个坐标点来确定的矩形),然后传递给Canvas绘制。

当然,后两者有什么区别呢?emmmm,最大的区别就是精度不同,Rect是int型的,而RectF是float型的,暂时不用太考虑它们直接的差距。

1
2
3
4
5
6
7
8
//第一种
canvas.drawRect(50, 50, 150, 150, mPaint);
//第二种
Rect rect = new Rect(50, 50, 150, 150);
canvas.drawRect(rect, mPaint);
//第三种
RectF rectF = new RectF(50, 50, 150, 150);
canvas.drawRect(rectF, mPaint);

绘制圆角矩形:

绘制圆角矩形也提供了两种重载方式,然而第二种方法是在API21之后才会添加,所以一般用第一种。

1
2
3
4
5
//第一种
RectF rect = new RectF(50, 50, 250, 250);
canvas.drawRoundRect(rect, 30, 30, mPaint);
//第二种
canvas.drawRoundRect(50, 50, 250, 250, 30, 30, mPaint);

对于第一种方法中,两个30分别代表参数 rx 和 ry,这两个参数分别代表椭圆的两个半径。

绘制圆:

前两个参数为圆心坐标,后一个参数为半径,最后为画笔。

1
canvas.drawCircle(100, 100, 50, mPaint);

绘制圆弧:

1
2
3
4
5
6
// 第一种
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint){}
// 第二种
public void drawArc(float left, float top, float right, float bottom, float startAngle,
float sweepAngle, boolean useCenter, @NonNull Paint paint) {}

可以看出,绘制圆弧的时候要传入一个矩形对象,然后是起始角度,扫过角度,是否使用中心点和画笔,矩形的中心则代表我圆弧的圆心。

1
2
3
4
5
6
//无中心点
RectF rectF = new RectF(100, 100, 300, 300);
canvas.drawArc(rectF, 0, 90, false, mPaint);
//有中心点
RectF rectF1 = new RectF(100, 200, 300,400);
canvas.drawArc(rectF1, 0, 90, true, mPaint);

Paint简介

绘制的基本形状由Canvas确定,但绘制出来的颜色、具体效果则由Paint确定

设置画笔样式(mPaint.setStyle())有三种:

  • Paint.Style.STROKE //描边
  • Paint.Style.FILL //填充
  • Paint.Style.FILL_AND_STROKE //描边加填充

绘制饼状图

其实上面的基本操作自己都动手试试的话,画一个饼状图并不是什么难事。首先要明确思路,就是画饼状图需要哪些元素,只需要一个元素,即角度。角度可以由数据占总数据的百分比算出,然后是画线以及文字。

效果如下:

感觉还不错的呢,代码详见:

https://github.com/Omooo/ChartsDemo

求个Star,就是给我最大的鼓励了。QwQ

我们一直都向往,面朝大海,春暖花开。 但是几人能做到,心中有爱,四季不败?