如何在Android Canvas中设置includeFontPadding为false以消除字体内边距
Canvas绘制文本消除字体内边距的实现方案
方案一:API 26+ 直接禁用字体padding(推荐)
从Android 8.0(API 26)开始,Font.Builder提供了setIncludePadding(false)方法,和TextView的android:includeFontPadding="false"效果完全一致,能直接去掉字体自带的上下padding。
代码示例:
val paint = Paint() // 从字体资源创建Font实例并禁用padding val typeface = ResourcesCompat.getFont(mContext, R.font.default_font) val font = Font.Builder(typeface) .setIncludePadding(false) .setSize(35f) // 设置字体大小,替代paint.textSize .build() paint.font = font paint.textAlign = Paint.Align.CENTER canvas.drawText("some text", 50f, 60f, paint)
方案二:兼容低版本(API <26)手动调整基线
如果需要支持API 26以下的设备,就得通过FontMetrics计算字体的额外padding,手动调整绘制的基线位置,从而消除上下多余空间。
核心原理:
字体的FontMetrics中,top和bottom包含了字体自带的额外padding,而ascent和descent才是字符实际的上下边界。我们需要调整基线位置,让文本只在ascent到descent的范围内绘制,剔除top到ascent、descent到bottom的冗余空间。
代码示例:
val paint = Paint() val plain: Typeface? = ResourcesCompat.getFont(mContext, R.font.default_font) paint.typeface = Typeface.create(plain, Typeface.NORMAL) paint.textSize = 35f paint.textAlign = Paint.Align.CENTER val text = "some text" val fontMetrics = paint.fontMetrics // 计算调整后的基线位置,让文本中心对齐原坐标(50f,60f)且无padding val textCenterOffset = (fontMetrics.ascent + fontMetrics.descent) / 2 val baselineY = 60f - textCenterOffset // 绘制文本 canvas.drawText(text, 50f, baselineY, paint)
验证方式:
可以绘制辅助线直观查看效果:
// 原基线(红色) canvas.drawLine(0f, 60f, canvas.width.toFloat(), 60f, Paint().apply { color = Color.RED }) // 调整后的基线(绿色) canvas.drawLine(0f, baselineY, canvas.width.toFloat(), baselineY, Paint().apply { color = Color.GREEN }) // 文本实际上下边界(蓝色) val textTop = baselineY + fontMetrics.ascent val textBottom = baselineY + fontMetrics.descent canvas.drawLine(0f, textTop, canvas.width.toFloat(), textTop, Paint().apply { color = Color.BLUE }) canvas.drawLine(0f, textBottom, canvas.width.toFloat(), textBottom, Paint().apply { color = Color.BLUE })
内容的提问来源于stack exchange,提问作者Muhammed Aydogan
相关产品推荐
相关产品推荐

