如何调整EditText光标高度以匹配Digory Doodles字体?
解决自定义字体导致EditText光标高度异常及尺寸拉伸问题
这个问题我之前碰到过好几个开发者都遇到过,本质是Digory Doodles字体的元数据不规范——很多免费手绘字体没有完善行高、基线、字符边界等核心参数,导致Android系统计算EditText的光标高度、控件尺寸时出现偏差。下面给你几个按优先级排序的解决方案:
1. 修复字体文件(最彻底,推荐)
直接修正字体的元数据,让系统能正确识别它的排版参数,这是一劳永逸的办法。你可以用免费的字体编辑工具FontForge来操作:
- 下载并打开FontForge,导入你的
Digory Doodles.ttf文件 - 点击顶部菜单栏「Element」→「Font Info」,切换到「OS/2」标签页
- 找到「Win Ascent」「Win Descent」「Typo Ascent」「Typo Descent」这几个参数,把它们调整到和字体实际字形匹配的数值(比如参考系统默认Roboto字体的比例,或者直接取字体里最高字符到最低字符的实际高度)
- 再切换到「PostScript」标签页,确认「Font Bounding Box」的数值和字体实际边界一致
- 保存修改后的字体,替换assets目录里的原文件,重新运行测试
2. 自定义EditText(代码层面适配,无需改字体)
如果没法修改字体文件,那就自己写个自定义EditText,手动控制光标高度和控件尺寸:
class CustomEditText @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.editTextStyle ) : AppCompatEditText(context, attrs, defStyleAttr) { override fun onDraw(canvas: Canvas?) { // 把光标高度设为行高的80%,你可以根据实际效果调整比例 val lineHeight = lineHeight val targetCursorHeight = (lineHeight * 0.8f).toInt() cursorDrawable?.apply { // 计算光标上下偏移,让它垂直居中于文本 val topOffset = (lineHeight - targetCursorHeight) / 2 setBounds(0, topOffset, cursorWidth, topOffset + targetCursorHeight) } super.onDraw(canvas) } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) // 强制让EditText高度适配实际文本高度,避免wrap_content被异常拉伸 val textActualHeight = paint.fontMetrics.bottom - paint.fontMetrics.top val desiredHeight = textActualHeight.toInt() + paddingTop + paddingBottom setMeasuredDimension(measuredWidth, desiredHeight) } }
然后在你的布局文件里,把原来的EditText替换成这个CustomEditText,再按原来的方式设置字体就可以了。
3. 临时应急方案(快速调整,适合测试)
如果不想写自定义View,也可以试试通过布局属性快速调整:
- 给EditText添加
android:paddingTop和android:paddingBottom,用内边距把多余的空间挤掉,让控件高度适配文本 - 设置
android:lineSpacingMultiplier="0.9"(数值可以自己调),缩小行高来匹配光标高度 - 还可以自定义光标样式:创建一个高度合适的drawable文件(比如
cursor.xml),然后设置android:textCursorDrawable="@drawable/cursor",直接指定光标高度
补充说明
为什么其他字体正常?因为系统自带字体或者规范的商业字体都严格遵循了排版规范,完善了所有元数据参数,Android系统能准确计算光标、行高和控件尺寸;而Digory Doodles这类手绘字体通常是个人制作,没做这些专业优化,所以才会出现异常。
内容的提问来源于stack exchange,提问作者rupinderjeet
相关产品推荐
相关产品推荐

