2D绘图的学习Paint,Canvas(二)

前言

上一节,学会了Paint,Canvas的基本用法后,这一节,学习Paint的高级用法。还没看过上一节的请点击这里:Android_2D绘图的学习Paint,Canvas(一)。

一,文字的绘制

在做UI的时候,常常会绘制文字,Canvas绘制文字时,主要考虑到字体的宽度和高度问题。字体的宽度比较好理解,这里我们主要考虑一下字体的高度。 先看一张图,网上搜的:

这里说明了在安卓中绘制字体时对于高度的划分:top,ascent,baseLine,descent,bottom.有点类似我们刚开始学英语的时候的练习本。字体的高度我们取得是ascent到descent的距离。经过我测试,系统自带的TextView中,绘制的背景高度为top到bottom的距离。字体的起始坐标点默认是baseLine中最左边的一个点,可以通过调用Paint.setTextAlign(Paint.Align align)方法设置中间还是最右边。 我们先来绘制一个正确的文字居中的一个效果:

代码:

private Paint mPaint;private String mText = “Android Paint学习”;public PaintView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mPaint = new Paint();mPaint.setColor(Color.BLACK);mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 20, getResources().getDisplayMetrics()));}public PaintView(Context context, AttributeSet attrs) {this(context, attrs, 0);// TODO Auto-generated constructor stub}public PaintView(Context context) {this(context, null);// TODO Auto-generated constructor stub}(int widthMeasureSpec, int heightMeasureSpec) {//得到文字宽度int textWidth = (int) mPaint.measureText(mText);//得到文字高度int textHeight = (int) (mPaint.descent() – mPaint.ascent());// 设置View的高度和宽度为字体的高度和宽度widthMeasureSpec = MeasureSpec.makeMeasureSpec(textWidth,MeasureSpec.EXACTLY);heightMeasureSpec = MeasureSpec.makeMeasureSpec(textHeight,MeasureSpec.EXACTLY);super.onMeasure(widthMeasureSpec, heightMeasureSpec);}(Canvas canvas) {//这里减去了一个descent主要是画笔画文字的基准线为baseLine,如果不剪,,就会出现底部有一部分看不到的情况canvas.drawText(mText, 0, getHeight() – mPaint.descent(), mPaint);}

明显可以看出系统的TextView要高一点。注意top和ascent的值都是负值,所以在获取高度时,是减去ascent。如果要像TextView一样的高度的方法代码:

FontMetrics fm = mPaint.getFontMetrics();int textHeight = (int) (fm.descent – fm.top+2);

因为Paint没有top()这个方法所以我们用FontMetrics中的top属性。 这里参考了一篇博文:Android字体高度的研究讲的很详细的。

二,Paint.Cap

The Cap specifies the treatment for the beginning and ending of stroked lines and paths. The default is BUTT.

cap是帽子,覆盖的意思,在画笔中,就是指定边缘点(画笔第一点,和画笔最后一点)的样式。 一共有3种样式:BUTT,ROUND,SQUARE. 我都以画一段圆弧来说明,效果:

从左至右分别是:SQUARE,ROUND,BUTT一看图,就了然了。 代码:

mPaint.setColor(Color.RED);mPaint.setStrokeWidth(2);canvas.drawLine(0, 50, getWidth(), 50, mPaint);mPaint.setStrokeWidth(30);mPaint.setStyle(Style.STROKE);mPaint.setAntiAlias(true);mPaint.setColor(Color.BLACK);mPaint.setStrokeCap(Cap.BUTT);canvas.drawArc(new RectF(-getWidth() + 150, -getHeight() + 150,getWidth() – 50, getHeight() – 50), 0, 50, false, mPaint);mPaint.setStrokeCap(Cap.ROUND);canvas.drawArc(new RectF(-getWidth() + 100, -getHeight() + 150,getWidth() – 100, getHeight() – 50), 0, 50, false, mPaint);mPaint.setStrokeCap(Cap.SQUARE);canvas.drawArc(new RectF(-getWidth() + 50, -getHeight() + 150,getWidth() – 150, getHeight() – 50), 0, 50, false, mPaint);三,Paint.join

The Join specifies the treatment where lines and curve segments join on a stroked path. The default is MITER. 摘自官方文档,就是说路径在转弯的时候指定其样式。 一共有3种样式:MITER,ROUND,BEVEL。 效果:

从左至右分别是:MITER,ROUND,BEVEL。 代码:

mPaint.setStrokeWidth(40);mPaint.setStyle(Style.STROKE);mPaint.setStrokeJoin(Join.MITER);Path path = new Path();path.moveTo(0, 30);path.lineTo(100, 30);path.lineTo(100, 100);canvas.drawPath(path, mPaint);mPaint.setStrokeJoin(Join.ROUND);Path path1 = new Path();path1.moveTo(200, 30);path1.lineTo(300, 30);path1.lineTo(300, 100);canvas.drawPath(path1, mPaint);mPaint.setStrokeJoin(Join.BEVEL);Path path2 = new Path();path2.moveTo(400, 30);path2.lineTo(500, 30);path2.lineTo(500, 100);canvas.drawPath(path2, mPaint);四,Paint.FontMetrics

调用Paint.getFontMetrics()会返回一个FontMetrics对象,调用前记得先设置字体大小,该对象有5个属性,分别是:top,ascent,descent,bottom,leading(行间距).注意前2个的值为负。

要铭记在心;每天都是一年中最美好的日子

2D绘图的学习Paint,Canvas(二)

相关文章:

你感兴趣的文章:

标签云: