参考:https://hencoder.com/ui-1-3/
练习github地址:https://github.com/fandazeng/ViewDemo
Canvas 绘制文字的方式
Canvas 的文字绘制方法有三个:drawText() drawTextRun() 和 drawTextOnPath()。
drawText(String text, float x, float y, Paint paint)
drawText() 是 Canvas 最基本的绘制文字的方法:给出文字的内容和位置, Canvas 按要求去绘制文字。方法的参数很简单: text 是文字内容,x 和 y 是文字的坐标。但需要注意:这个坐标并不是文字的左上角,而是一个与左下角比较接近的位置。
mPaint.setTextSize(100);
//y是基线,文本的左下角,x值没有贴着文本,有一点空隙,往左边一点
canvas.drawText("fanda", 200, 200, mPaint);
drawTextOnPath()
沿着一条 Path 来绘制文字。
drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)
参数里,需要解释的只有两个: hOffset 和 vOffset。它们是文字相对于 Path 的水平偏移量和竖直偏移量,利用它们可以调整文字的位置。例如你设置 hOffset 为 5, vOffset 为 10,文字就会右移 5 像素和下移 10 像素。
StaticLayout
StaticLayout 并不是一个 View 或者 ViewGroup ,而是 android.text.Layout 的子类,它是纯粹用来绘制文字的。 StaticLayout 支持换行,它既可以为文字设置宽度上限来让文字自动换行,也会在 \n 处主动换行。
构造方法:
StaticLayout(CharSequence source, TextPaint paint, int width, Layout.Alignment align, float spacingmult, float spacingadd, boolean includepad)
参数:
width 是文字区域的宽度,文字到达这个宽度后就会自动换行;
align 是文字的对齐方向;
spacingmult 是行间距的倍数,通常情况下填 1 就好;
spacingadd 是行间距的额外增加值,通常情况下填 0 就好;
includeadd 是指是否在文字上下添加额外的空间,来避免某些过高的字符的绘制出现越界。
//align 是文字的对齐方向,默认左对齐,还有居中和右对齐
StaticLayout staticLayout = new StaticLayout("hello\nfanda", mTextPaint,
1100,Layout.Alignment.ALIGN_CENTER, 1, 0, true);
canvas.save();
canvas.translate(200, 200);
staticLayout.draw(canvas);
canvas.restore();
Paint 对文字绘制的辅助
Paint 对文字绘制的辅助,有两类方法:设置显示效果的和测量文字尺寸的。
设置显示效果类
1.setTextSize(float textSize)
设置文字大小。
mPaint.setTextSize(50);
canvas.drawText("fanda", 200, 200, mPaint);
mPaint.setTextSize(60);
canvas.drawText("fanda", 200, 300, mPaint);
2.setTypeface(Typeface typeface)
设置字体,可以设置默认提供的字体样式,也可以使用自定义的字体。
//加粗
mPaint.setTypeface(Typeface.DEFAULT_BOLD);
canvas.drawText("zeng fanda", 200, 200 , mPaint);
//等宽字体
mPaint.setTypeface(Typeface.MONOSPACE);
canvas.drawText("zeng fanda", 200, 300, mPaint);
mPaint.setTypeface(Typeface.SANS_SERIF);
canvas.drawText("zeng fanda", 200, 400, mPaint);
mPaint.setTypeface(Typeface.SERIF);
canvas.drawText("zeng fanda", 200, 500, mPaint);
3.setFakeBoldText(boolean fakeBoldText)
设置字体加粗。
mPaint.setFakeBoldText(false);
canvas.drawText("fanda", 200, 200, mPaint);
mPaint.setFakeBoldText(true);
canvas.drawText("fanda", 200, 300, mPaint);
4.setStrikeThruText(boolean strikeThruText)
是否加删除线。
mPaint.setStrikeThruText(true);
canvas.drawText("fanda", 200, 300, mPaint);
5.setUnderlineText(boolean underlineText)
是否加下划线。
mPaint.setUnderlineText(true);
canvas.drawText("fanda", 200, 300, mPaint);
6.setTextSkewX(float skewX)
设置文字倾斜度。
mPaint.setTextSkewX(-0.3f);
canvas.drawText("fanda", 200, 300, mPaint);
7.setTextScaleX(float scaleX)
设置文字横向缩放。
mPaint.setTextScaleX(0.5f);
canvas.drawText("fanda", 200, 300, mPaint);
8.setLetterSpacing(float letterSpacing)
设置字符间距。默认值是 0。
paint.setLetterSpacing(0.2f);
canvas.drawText(text, 100, 150, paint);
9.setFontFeatureSettings(String settings)
用 CSS 的 font-feature-settings 的方式来设置文字。
paint.setFontFeatureSettings("smcp"); // 设置 "small caps"
canvas.drawText("Hello HenCoder", 100, 150, paint);
10.setTextAlign(Paint.Align align)
设置文字的对齐方式。一共有三个值:LEFT CETNER 和 RIGHT。默认值为 LEFT。
mPaint.setTextAlign(Paint.Align.LEFT);
canvas.drawText("hello fanda", 700, 200, mPaint);
mPaint.setTextAlign(Paint.Align.CENTER);
canvas.drawText("hello fanda", 700, 300, mPaint);
mPaint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText("hello fanda", 700, 400, mPaint);
11.setTextLocale(Locale locale)
设置绘制所使用的语言。Canvas 绘制的时候,默认使用的是系统设置里的 Locale。而通过
Paint.setTextLocale(Locale locale) 就可以在不改变系统设置的情况下,直接修改绘制时的 Locale。
paint.setTextLocale(Locale.CHINA); // 简体中文
canvas.drawText(text, 150, 150, paint);
paint.setTextLocale(Locale.TAIWAN); // 繁体中文
canvas.drawText(text, 150, 150 + textHeight, paint);
paint.setTextLocale(Locale.JAPAN); // 日语
canvas.drawText(text, 150, 150 + textHeight * 2, paint);
测量文字尺寸类
getFontSpacing()
获取推荐的行距。即推荐的两行文字的 baseline 的距离。这个值是系统根据文字的字体和字号
自动计算的。它的作用是当你要手动绘制多行文字(而不是使用 StaticLayout)的时候,可以
在换行的时候给 y 坐标加上这个值来下移文字。
canvas.drawText("hello fanda", 500, 200, mPaint);
canvas.drawText("hello fanda", 500, 200 + mPaint.getFontSpacing(), mPaint);
canvas.drawText("hello fanda", 500, 200 + mPaint.getFontSpacing() * 2, mPaint);
getTextBounds(String text, int start, int end, Rect bounds)
获取文字的显示范围。
参数里,text 是要测量的文字,start 和 end 分别是文字的起始和结束位置,bounds 是存储文字显示
范围的对象,方法在测算完成之后会把结果写进 bounds。
mPaint.getTextBounds(content,0,content.length(),mRect);
canvas.drawText(content, 200, 200, mPaint);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(3);
Log.d("bounds","left" + mRect.left + "==" + "top" + mRect.top + "==" + "right" + mRect.right + "==" + "bottom" + mRect.bottom);
// 6,-77,511,1 (相对于绘制文本的位置,即相对于左下角[200,200]这个点)
//206,123,711,201
mRect.left += 200;
mRect.right += 200;
mRect.top += 200;
mRect.bottom += 200;
canvas.drawRect(mRect,mPaint);
float measureText(String text)
测量文字的宽度并返回。
mPaint.setTextSize(100);
canvas.drawText(text1, 200, 200, mPaint);
text1_width = mPaint.measureText(text1);
mPaint.setTextSize(150);
mPaint.setColor(Color.RED);
canvas.drawText(text2, 200 + text1_width, 200, mPaint);
text2_width = mPaint.measureText(text2);
mPaint.reset();
mPaint.setTextSize(100);
canvas.drawText(text3, 200 + text1_width + text2_width, 200, mPaint);
练习演示: