You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Java:自定义UnderlinedEditText对阿拉伯语等语言适配异常求助

解决自定义下划线EditText在阿拉伯语等语言下文字偏移问题

你的问题出在自定义下划线的baseline计算逻辑上:通过初始baseline累加getLineHeight()的方式,无法适配阿拉伯语等带有字形延伸或RTL布局的语言,导致下划线位置偏上,文字跑到下划线下方。

修改后的代码

public class UnderlinedEditText extends androidx.appcompat.widget.AppCompatEditText {
    private final Paint mPaint;

    public UnderlinedEditText(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.BLACK);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // 获取Layout对象,它能准确提供每一行的排版信息
        Layout layout = getLayout();
        if (layout == null) {
            super.onDraw(canvas);
            return;
        }

        int lineCount = layout.getLineCount();
        for (int i = 0; i < lineCount; i++) {
            // 获取当前行的baseline,这是文字排版的基准线
            int baseline = layout.getLineBaseline(i);
            // 获取当前行的左右边界,确保下划线宽度和文字匹配
            int left = (int) layout.getLineLeft(i);
            int right = (int) layout.getLineRight(i);
            // 在baseline下方1px处绘制下划线
            canvas.drawLine(left, baseline + 1, right, baseline + 1, mPaint);
        }

        super.onDraw(canvas);
    }
}

关键修改点说明

  • 使用Layout对象获取准确行信息:getLayout()返回的Layout包含了每一行的精确排版数据,包括baseline、行宽等,能适配不同语言的字形差异。
  • 逐行获取baseline:通过getLineBaseline(i)直接拿到每一行的基准线位置,避免了手动累加lineHeight带来的偏移误差。
  • 匹配文字宽度的下划线:用getLineLeft(i)和getLineRight(i)获取当前行的实际文字宽度,下划线不会超出文字范围,视觉更合理。

关于setElegantTextHeight(true)的说明

这个属性主要是让EditText在处理多行文字时,为带有上下延伸的字形预留足够高度,但它只影响EditText自身的文字排版空间,不会修正你自定义下划线的计算逻辑,所以单独设置它无法解决问题。

内容的提问来源于stack exchange,提问作者Nader

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 08:50:28