Android 自定义绘制之文字测量知识点

本文介绍了如何在Android自定义View中绘制文字并实现居中,包括静态文字的居中处理、动态文字的基准线调整,以及文字贴边和多行文字的绘制方法,特别提到了StaticLayout在纯文字和图文混排中的应用。
摘要由CSDN通过智能技术生成


一、如何绘制文字,并居中显示

现在我们自定义一个View,绘制一个圆环,并在圆环中间画一串文字

private val paint = Paint()
private val content = "abc"
private var bounds = Rect()

init {
    paint.style = Paint.Style.STROKE
    paint.strokeWidth = 2f.dp
    paint.textSize = 50f.dp
    paint.textAlign = Paint.Align.CENTER
}

override fun onDraw(canvas: Canvas) {
    super.onDraw(canvas)
    canvas.translate(width / 2f, height / 2f)
    canvas.drawCircle(0f, 0f, 100f.dp, paint)
    paint.style = Paint.Style.FILL
    paint.getTextBounds(content, 0, content.length, bounds)//获取文字内容的边界
    canvas.drawText(
        content,
        0f,
        0f - (bounds.top + bounds.bottom) / 2, //y值需要减去1/2字的占用高度
        paint
    )
}

生成的效果如下:
在这里插入图片描述

二、动态文字如何居中

上面的写法只是针对静态文字的绝对居中,但如果文字换成“abcq”,那么其中的“abc”就会略微向上移动,如果是动态变化的文字,就会造成文字的高低动态变化,显得很乱,那么动态变化的文字如何居中呢

1. 绘制文字时的5条基准线

借用一张网图:
在这里插入图片描述

Top:最高字符到baseline的值,即ascent的最大值,为负数
Ascent:字符最高处到baseline的值,为负数
Baseline:基线,字符在TextView中的基准点
Descent:字符最低处到baseline的值,为正数
Bottom:最低字符到baseline的值,即descent的最大值,为正数

2. 调整文字居中

val metrics = FontMetrics()
paint.getFontMetrics(metrics)
canvas.drawText(
    content,
    0f,
    0f - (metrics.ascent + metrics.descent) / 2, //y值需要减去实际文字高度一半
    paint
)

通过使用ascent和descent,来确定动态文字的y值

三、文字贴边

根据UI的实际要求
上端贴边有三种方式,分别是利用TextBounds的top、FontMatrics的top或者ascent 三个值,来去掉边。
下端贴边有三种方式,分别是利用TextBounds的bottom、FontMatrics的bottom或者descent 三个值,来去掉边。
左端贴边用TextBounds的left。
右端贴边用TextBounds的right。

四、多行文字绘制

1. 纯文字

自动换行可以使用StaticLayout,Android的TextView也是用的StaticLayout

2. 图文

图文混排时,需要让文字避开图片,所以不能用StaticLayout,需要我们自行断行

Paint.class
//第一次断行时可以用                         
public int breakText(String text, boolean measureForwards,
                         float maxWidth, float[] measuredWidth)
//从第二行开始断行时使用
public int breakText(CharSequence text, int start, int end,
                         boolean measureForwards,
                         float maxWidth, float[] measuredWidth)

同时我们需要知道每一行的y值: - fontMatrics.top + lineCount(行数) * paint.fontSpacing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ByeMoon丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值