多行 EditText 的光标高度问题

时间:2023-02-01 08:56:03

问题

改变文本的行间距需要给 EditText 设置 lineSpacingExtralineSpacingMultiplier 这个时候的 EditText的光标高度就会变得很难看.

多行 EditText 的光标高度问题

解决办法

自定义 cursorDrawable 然后设置 padding

原理

EditText 在更新光标的视图的时候检查了光标 drawable 的 padding. 计算光标高度会算上相应的值.

相关源码:

Editor.java

private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
    // ...

    if (mTempRect == null) mTempRect = new Rect();
    mCursorDrawable[cursorIndex].getPadding(mTempRect); //光标的 padding

    // ...

    // 上下边距的最终值为 top - mTempRect.top 和 bottom + mTempRect.bottom
    mCursorDrawable[cursorIndex].setBounds(left, top - mTempRect.top, left + width,
            bottom + mTempRect.bottom);

}

那么 top 和 bottom 的值是多少 ?

Editor.java

void updateCursorsPositions() {
    //...

    Layout layout = mTextView.getLayout();
    Layout hintLayout = mTextView.getHintLayout();
    final int offset = mTextView.getSelectionStart();
    final int line = layout.getLineForOffset(offset); // 算出当前是第几行
    final int top = layout.getLineTop(line); // 算出第 line 行的顶部坐标
    final int bottom = layout.getLineTop(line + 1); // 算出第 line+1 行的顶部坐标

    // ...

    boolean clamped = layout.shouldClampCursor(line);
    updateCursorPosition(0, top, middle,
            getPrimaryHorizontal(layout, hintLayout, offset, clamped));

    // ...
}

从源码看出 bottom 到 top 的距离为第 line 行的顶部到第 line+1 行的顶部. 也就是上面图中的效果.

解决方法:
自定义一个 cursor.xml, 然后设置 android:textCursorDrawable="@drawable/cursor"

cursor.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
    <size  android:width="2dip" />
    <solid  android:color="#f00" />
    <padding  android:top="0dp" android:bottom="-22dp" />
</shape>

注意上面设置了 shape 的 padding 计算出来 bottom = 行高 - 文字高度 = 42 - 20 = 22.当然这值是可以自己调整的.

多行 EditText 的光标高度问题

文章来自: http://hanks.xyz