Android 编辑文本行距额外值和光标位置问题

Android 编辑文本行距额外值和光标位置问题,android,positioning,text-editor,font-size,cursor-position,Android,Positioning,Text Editor,Font Size,Cursor Position,我正在尝试使用大量行距制作一个Edittext。它正在工作,但光标不在正确的位置。请看下图。如您所见,光标位于两行之间的中间。 以下是编辑文本代码:- <EditText android:id="@+id/editText1" android:layout_width="match_parent" android:layout_height="wrap_content" android

我正在尝试使用大量行距制作一个
Edittext
。它正在工作,但光标不在正确的位置。请看下图。如您所见,光标位于两行之间的中间。 以下是编辑文本代码:-

     <EditText
            android:id="@+id/editText1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/transparent"
            android:fadingEdge="vertical"
            android:gravity="left|center_vertical"
            android:lineSpacingExtra="10dp"
            android:lineSpacingMultiplier="2"
            android:padding="18dp"
            android:scrollbars="vertical"
            android:textSize="22sp" >

            <requestFocus />
        </EditText>


答案是您必须使用android:textCursorDrawable=“@drawable/name\u of_your\u drawable”并设置您自己的光标可绘制性,在填充中,您应该设置android:bottom=“-20sp”(或您的文本大小)的值。如示例所示

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.androisxxxsxsxd.com/apk/res/android"
    android:shape="rectangle" >
    <size 
        android:width="2dip" />
    <solid
        android:color="@color/red" />
    <padding 
        android:top="2sp"
        android:bottom="-20sp" />
</shape>

myxml


如果将
textCursorDrawble
lineSpacingExtra
一起使用,则会出现另一个问题:当应用程序在棒棒糖上方运行时,因为如果在自定义
textCursorDrawable
中定义了负底部填充,则最后一行的行高度不会更改,光标将在最后一行收缩,如下所示:

为了获得更显著的效果,我将
lineSpacingExtra
设置为
8dp
,并且我的自定义
textCursorDrawable
的一部分是
。因此,您可以在最后一行中看到小光标

我们当然不喜欢这样。我在网上搜索了好几个小时,好几天,但没有一个页面能帮上忙。但如果你看到了这个答案,不要担心,因为我已经用我的方式解决了这个问题,虽然有点粗糙,但据我所知效果很好

问题的根本原因是,我们在
文本cursordrawable
中设置了底部填充,使所有行的长度缩短。假设文本大小是12dp,那么原始行高度也是12dp(只是让事情变得更简单)。定义
行间距xtra=“8dp”
后,行高将增加到20dp。如果我们不对
textCursorDrawable
做任何操作,光标高度现在也将是20dp,这显然比文本大小长,因此我们将其缩短,通过在自定义
textCursorDrawable
形状xml文件中定义
来切割底部8dp。但是,在棒棒糖上面,最后一行的
lineSpacingExtra
被忽略,因此该行的高度保持在12dp。如果不使用自定义光标,则最后一行的光标也是如此。然后我们切下8dp,现在我们看到一个4dp光标,这是错误的,而正确的操作是停止在custom
textCursorDrawable中设置-8dp底部填充

因此,解决方案是:对普通行和最后一行使用不同的
textCursorDrawable
,对特殊行表示足够的尊重

那么,我们应该在什么时候更改
文本cursordrawable
?我的答案是:当用户单击编辑文本的最后一行时。这是合理的,因为光标只能在该操作之后出现(如果用户在此之后单击“enter”,则可能不是最后一次操作,但这不会影响我们的解决方案)

下一步是监听用户点击最后一行。我的解决方案很粗糙:

mEditText.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            EditText et = (EditText) v;
            // lineSpacingExtra's unit is px.
            int lastLineHeight = (int) (et.getLineHeight() - et.getLineSpacingExtra());
            if (et.getHeight() - event.getY() <= lastLineHeight) {
                setTextCursorDrawable(et, lastLineCursorRes);
            } else {
                setTextCursorDrawable(et, normalCursorRes);
            }
            return true;
        }
        return false;
    }
});
最后,lastLineCursorRes的特殊部分是:

好的,给你。请注意,我在尝试这个解决方案并发现它有效后写下了这个答案,这意味着我没有仔细检查它。如果您在使用此解决方案时遇到任何问题,请发表评论

参考资料


要知道为什么在
TextView
及其子类的最后一行中忽略了
lineSpacingExtra/Multiplier
,请选中:,和。

android:gravity=“left | center_vertical”Remove center_vertical.@RahulGupta您得到正确的工作解决方案了吗。。?请与SO分享
mEditText.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            EditText et = (EditText) v;
            // lineSpacingExtra's unit is px.
            int lastLineHeight = (int) (et.getLineHeight() - et.getLineSpacingExtra());
            if (et.getHeight() - event.getY() <= lastLineHeight) {
                setTextCursorDrawable(et, lastLineCursorRes);
            } else {
                setTextCursorDrawable(et, normalCursorRes);
            }
            return true;
        }
        return false;
    }
});
public void setTextCursorDrawable(EditText et, @DrawableRes int res) {
    try {
        Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
        f.setAccessible(true);
        f.set(et, res);
    } catch (Exception ignored) {}
}