文章目录
前言
一行文字在View中垂直居中不是一件容易的事情,下面针对静态文字和动态文字(内容会变动)的情况提出两种居中的方案。
一、静态文字垂直居中?
由于静态文字不怎么变动,我们只需要测量出这段文字的bounds
,在垂直方向上减去中心点的偏移就可以实现居中
code
//静态文字内容
private const val CONTENT = "abcp"
//TextBounds读入到bounds这个Rect中
private val bounds = Rect()
绘制文字
paint.getTextBounds(CONTENT, 0, CONTENT.length, bounds)
canvas.apply {
drawText(CONTENT, width / 2f, height / 2f - (bounds.top + bounds.bottom) / 2, paint)
}
在中间位置画一条辅助线做比对
paint.strokeWidth = 1.dp
drawLine(0f, height / 2f, width.toFloat(), height / 2f, paint)
效果
二、动态文字垂直居中
你可能会好奇,为什么动态文字不继续用上面静态文字的解决方案呢?不是很方便简洁吗?
来看这张图,由于他们测量出的bounds(圆框)高度不同,那么偏移量也不同,如果文字由图中的abcd---->ajp,那么是不是由于中心点偏移量不同,我们绘制文字时减去的偏移量也不同,文字由abcd–>ajp就会有一个上下跳动的过程,最终文字是在最中心的位置上了,但是呢?会给用户一个跳动的效果展现,这肯定不行,用户不会觉得我们文字对的准,只会觉得我们软件垃圾。
解决方案
利用ascent 和descent计算垂直方向的中心偏移量
由于ascent 和descent和我们的字体相关,不管你绘制什么文字,这两个值时不变的,那么我们在绘制动态文字的时候用这两个值算垂直方向的中心偏移量就是不变的,那么文字变化时就不会有跳跃效果
code:
drawText(
CONTENT,
width / 2f,
height / 2f - (paint.descent() + paint.ascent()) / 2,
paint
)
效果:
这行文字看上去确实不怎么垂直居中,明显有点头重脚轻,是一种折中的垂直居中方式。