前言
这一篇将介绍一个稍微高级一点的用法,主要用到的一个API,drawTextOnPath,当然也要用到上一篇的知识。
如果没有绘图相关知识的画,建议先看我的《博客绘图(一,基础知识)》这篇博客。
好了先看看效果吧~
看到了效果是不是很炫,现在的应用一般都有个引导也,如果在做炫一点是不是可以做到引导页里,让人感觉眼前一亮的感觉
还是先看文档吧,之前已经说了,需要用到一个API,drawTextOnPath,那么就来先看看这个API,这个API是canvas的一个方法
RetValue | method | describe |
---|---|---|
void | drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) | Draw the text, with origin at (x,y), using the specified paint, along the specified path. |
void | drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint) | Draw the text, with origin at (x,y), using the specified paint, along the specified path. |
这次就不翻译了,先看看第一条的描述吧
Draw the text, with origin at (x,y), using the specified paint, along the specified path
大致可以看出意思来,使用特别的画笔(也就是由自己设定好了的),沿着特定的路径,绘制一个带有最初位置(x,y)的文本。
除了X,Y其他的意思都能明白,最初的位置X,Y到底是哪个位置?好像并不知道,好吧,再进一步看看这个API的详细信息
public void drawTextOnPath (String text, Path path, float hOffset, float vOffset, Paint paint)
Draw the text, with origin at (x,y), using the specified paint, along the specified path. The paint’s Align setting determins where along the path to start the text.
Parameters
params | describe |
---|---|
text | String: The text to be drawn |
path | Path: The path the text should follow for its baseline |
hOffset | float: The distance along the path to add to the text’s starting position |
vOffset | float: The distance above(-) or below(+) the path to position the text |
paint | Paint: The paint used for the text (e.g. color, size, style) |
从文档中查阅到多了这么一句话”The paint’s Align setting determins where along the path to start the text.“那么可以联想到,x,y的位置可能和paint‘Align有关,知道Align是对齐的意思,好~再去paint类中看一下这个API
找到了这个方法,设置文本的对齐方式
RetValue | method | describe |
---|---|---|
void | setTextAlign(Paint.Align align) | Set the paint’s text alignment. |
public void setTextAlign (Paint.Align align)
Set the paint’s text alignment. This controls how the text is positioned relative to its origin. LEFT align means that all of the text will be drawn to the right of its origin (i.e. the origin specifieds the LEFT edge of the text) and so on.
Parameters
params | describe |
---|---|
align | Paint.Align: set the paint’s Align value for drawing text. |
可以知道默认是向左对齐的
介绍完了之后,基本可以开始着手写代码了
从上面的效果图可以看出,使用了三段path.
所以开始声明变量如下:
final String Draw_text = "心情不好,好像屎~_~";
Path p [] = new Path[3];
Paint paint;
第一段路径,随便绘制7个点
p[0] = new Path();
p[0].moveTo(0, 0);
for (int i = 0; i < 7; i++) {
p[0].lineTo(i * 70, (float) (Math.random() *70));
}
第二段路径,按逆时针绘制一个椭圆
p[1] = new Path();
RectF rectF = new RectF(0, 0, 500, 300);
p[1].addOval(rectF, Path.Direction.CCW);
第三段路径,绘制一段弧
p[2] = new Path();
p[2].addArc(rectF, startAngle, 120);
private float startAngle = 60;
这里需要稍微注意一点绘制弧的API,三个参数的意思,要非常清楚
public void addArc (RectF oval, float startAngle, float sweepAngle)
Add the specified arc to the path as a new contour.
Parameters
params | describe |
---|---|
oval | RectF: The bounds of oval defining the shape and size of the arc |
startAngle | float: Starting angle (in degrees) where the arc begins |
sweepAngle | float: Sweep angle (in degrees) measured clockwise |
看到这里你可能还是看不懂startAngle 和sweepAngle 是什么意思
这里可以参考一下canvas的DrawArc
public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
Draw the specified arc, which will be scaled to fit inside the specified oval.
If the start angle is negative or >= 360, the start angle is treated as start angle modulo(取模) 360.
If the sweep angle is >= 360, then the oval is drawn completely. Note that this differs slightly from SkPath::arcTo, which treats the sweep angle modulo 360. If the sweep angle is negative, the sweep angle is treated as sweep angle modulo 360
The arc is drawn clockwise. An angle of 0 degrees correspond to the geometric angle of 0 degrees (3 o’clock on a watch.)
Parameters
params | describe |
---|---|
oval | RectF: The bounds of oval used to define the shape and size of the arc |
startAngle | float: Starting angle (in degrees) where the arc begins |
sweepAngle | float: Sweep angle (in degrees) measured clockwise |
useCenter | boolean: If true, include the center of the oval in the arc, and close it if it is being stroked. This will draw a wedge |
paint | Paint: The paint used to draw the arc |
如果不太清楚的话,我自己做了两张图帮助大家理解
startAnlge角度对应坐标
这张图是绘制弧形的例子
看到这里大致就能明白了
- startAngle 表示绘制弧形的起始角度
- sweepAngle 表示绘制弧形的扫描角度范围固定的
所以要想到达效果图就只需要startAngle不断发生改变就行了 。
startAngle += 1;
invalidate();
最后要知道一个函数就是invaliddate(),就是通知view重绘,意思就是再次执行ondraw()方法
Ok~终于告一段落了!
完整代码如下:
MainActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new CustemView(this));
}
CustemView
class CustemView extends View {
final String Draw_text = "心情不好,好像屎~_~";
Path p[] = new Path[3];
Paint paint;
private float startAngle = 180;
public TextView(Context context) {
super(context);
// 第一段路径,随便绘制7个点
p[0] = new Path();
p[0].moveTo(0, 0);
for (int i = 0; i < 7; i++) {
p[0].lineTo(i * 70, (float) (Math.random() * 70));
}
// 第二段路径,按逆时针绘制一个椭圆
p[1] = new Path();
RectF rectF = new RectF(0, 0, 500, 300);
p[1].addOval(rectF, Path.Direction.CCW);
// 第三段路径,绘制一段弧
p[2] = new Path();
p[2].addArc(rectF, 0, 120);
// 初始化画笔
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(1);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
// super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
canvas.translate(40, 40);
// 设置从右边开始绘制
paint.setTextAlign(Paint.Align.RIGHT);
paint.setTextSize(40);
// 绘制路径
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(p[0], paint);
paint.setStyle(Paint.Style.FILL);
// 沿着路径绘制一段文本
canvas.drawTextOnPath(Draw_text, p[0], -30, 30, paint);
canvas.translate(0, 200);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(p[1], paint);
paint.setStyle(Paint.Style.FILL);
// 沿着路径绘制一段文本
canvas.drawTextOnPath(Draw_text, p[1], -40, 40, paint);
canvas.translate(0, 500);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(p[2], paint);
paint.setStyle(Paint.Style.FILL);
// 沿着路径绘制一段文本
p[2].reset();
RectF rectF = new RectF(0, 0, 500, 300);
p[2].addArc(rectF, startAngle % 360, 120);
canvas.drawTextOnPath(Draw_text, p[2], -40, 40, paint);
startAngle += 1;
invalidate();
Log.i("info", "info");
}
}