最近在做自定义控件,偏展示的那种,视觉出的花里胡哨的,没有现成的,只好自己画。
在哪画
View 提供了一个 onDraw 方法,
//View 里面是空实现,所以要想画个圆弧,就可以继承 View 并重写 onDraw
protected void onDraw(Canvas canvas) {}
材料准备
画布 这是画画的地方,系统已经为我们提供好了,就是 onDraw 方法的入参 Canvas 类对象。
画笔 画画的时候有可能只用一支铅笔,有可能用到好几种笔刷。在 Android 里可以用 Paint 类对象来表示,并且画笔是可以带颜色的,就像蜡笔一样五颜六色。
颜料 如果画的是油画或者水彩,笔刷需要配着颜料才能画出颜色。在 Android 里省去了这步,可以直接在 Paint 对象设置颜色,这样画笔就带上了颜色。
小画家 当然是我们啦,想画啥画啥。
延伸概念
Android 坐标系 以我们面对这屏幕,左上角为坐标原点,向右为 x 轴正方向,向下为 y 轴正方向。还有涉及到角度时,请拿出我们的左手,竖起大拇指,握起其他手指,放在手机屏幕上,大拇指朝向就是 z 轴正方向,其他手指握起的方向就是角度的正方向,以 x 轴的正半轴为 0 度角,转到 y 轴正半轴就是 90 度。(其实就是顺时针方向,与极坐标系相反)
画个圆弧试试看
系统提供了一些基本的形状绘画功能,画线,画圆,写个字,描个点等等,当然系统也提供了画圆弧的方法。虽然现实中,画什么东西是我们小画家在操作,但在 Android 交给了 Canvas 来负责,(也就是 Canvas 类提供了这些功能方法)我们小画家只要告诉 Canvas 对象要画什么就可以了。
//系统提供了两种方法来画圆弧,两者大同小异
//1.要告诉画布用什么画笔 2.要告诉画布从哪个角度开始话,圆弧扫过多少角度
//3.要告诉画布在画布的什么区域内画这个圆弧(两种表现形式,由两个坐标点确定一个矩形区域;由一个表示矩形区域的类 RectF 表示
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint)
drawArc(float left, float top, float right, float bottom, float startAngle,
float sweepAngle, boolean useCenter, Paint paint)
区域范围 正如 drawArc 方法入参提到的,应该画任何东西都要确定一个位置和范围,这个范围应该小于等于整个画布,但画布感觉是无边际的(虽然手机屏幕只有这么大,但画布应该是可以超出屏幕),所以画某个具体图形的范围也可以无限大,只不过实际都会指定一个可见范围,不然意义就不大了。
这个区域范围可以用 RectF 类表示,也可以用 左,上,右,下四个值来限定。其实这个区域范围有点类似 PS 的选区,框选某个范围后,只有那个区域画画才生效,超出了边界,再怎么画也是看不到的。当然,Android 的这个区域范围可能还影响这最终画出来的图形形状。
Paint arcPaint;
RectF arcRect;
private void init() {
arcPaint = new Paint();
arcPaint.setStyle(Paint.Style.STROKE);
arcPaint.setAntiAlias(true);
//注意 px 与 dp 的换算
arcPaint.setStrokeWidth(5);
arcPaint.setStrokeCap(Paint.Cap.ROUND);
arcPaint.setColor(Color.RED);
arcRect = new RectF();
//注意 px 与 dp 的换算
arcRect.set(0, 0, 100, 100);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawArc(arcRect, 0, 360, false, arcPaint);
}
再来说下渐变色的实现。系统提供了 Shader 类来控制颜色的变化,渐变也算一种。像如果需要给圆弧设置颜色渐变就可以用 Shader 的子类 SweepGradient。
//指定扫射圆心 cx, cy
//指定渐变色色值数组
//对应色值数组,用来控制对应色值的权重,如为 null,就按系统的均匀划分吧
SweepGradient(float cx, float cy, int colors[], float positions[])
//确定好渐变色后,只要把这个渐变色效果设置给画笔,画笔就能带着颜色画出来了
arcPaint.setShader(sweepGraditent);
关于 SweepGradient 还有一点要说,就是如果某段圆弧是包含了 0 度角的,那么在颜色渐变上为了过渡顺畅,需要起始颜色和终点颜色设置成一样。就像这样,
最后,会画圆弧了,可以用来表示什么呢?例如,油表盘,刻度盘,环形进度条(当然这个现成的也有)等等。