繁体   English   中英

如何在 android 的多行编辑文本中更改 cursor position?

[英]How to change cursor position in a multiline edittext in android?

首先,我已经阅读了关于此事的其他问题,但我正在尝试不同的东西。

我有一个多行 EditText,下面是 XML:

<EditText
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textColor="@color/textBodyColor"
        android:id="@+id/editScriptET"
        android:isScrollContainer="true"
        android:scrollbars="vertical"
        android:textSize="@dimen/font20"
        android:hint="@string/details"
        android:fontFamily="@font/courier_prime"
        android:inputType="textMultiLine"
        />

我想要做的是在单击菜单项时将 cursor 设置在一行的中心或一行的左侧(在该多行 EditText 中)。 因此,当我单击一个菜单项时,我希望 cursor 移动到 EditText 中当前行的中心。 当按下另一个菜单项时,我需要当前行左侧的 cursor 到 go。 (所有菜单项始终显示在工具栏上。)

有没有办法做到这一点?

我试过scriptET.setGravity(Gravity.CENTER); (其中scriptET是对我的 EditText 的引用),但没有任何反应。

编辑:使用评论中收到的建议,我设法将 cursor 设置在左侧,并使用Selection.moveToLeftEdge(scriptET.getText(), scriptET.getLayout()); . 使用一些 Toasts 消息,我注意到getLayout()方法给出了 null,但 cursor 在单击时仍然移动到当前行的左侧。

此外,当该行为空时,无法将 cursor 移动到“逻辑”中心,我真的需要这样做。

任何建议都非常感谢!

有一个android.text.Selection class 允许您在 EditText 中移动 cursor:

要将 cursor 移动到行的左侧,请使用Selection.moveToLeftEdge(edt.getText(), edt.getLayout()) 还有一种方法可以移动当前行右侧的 cursor。

将 cursor 移动到线的中心有点复杂。 首先,您必须确定线条的“中心”是什么意思。 例如,如果我们有以下行:

WWWWWWWWWWWWWWWWWWWWWWWWWllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll

它由 25 个大写的 Ws 和 25 个小写的 Ls 组成。 在这条线上,中心是在 Ws 和 Ls 的交界处(位置 25)还是在 Ws 块内的某个地方? 我们称前者为“逻辑”中心,后者为“视觉”中心。

这是将 cursor 移动到逻辑中心的方法:

public void moveToLogicalLineCenter(EditText edt) {
    Spannable text = edt.getText();
    Layout layout = edt.getLayout();

    // Find the index of the line that cursor is currently on.
    int pos = Selection.getSelectionStart(text);
    int line = layout.getLineForOffset(pos);

    // Find the start pos and end pos of that line.
    int lineStart = layout.getLineStart(line);
    int lineEnd = layout.getLineEnd(line);

    // Calculate center pos and set selection.
    int lineCenter = Math.round((lineEnd + lineStart) / 2f);
    Selection.setSelection(text, lineCenter);
}

这是将 cursor 移动到视觉中心的方法:

public void moveToVisualLineCenter(EditText edt) {
    Spannable text = edt.getText();
    Layout layout = edt.getLayout();

    // Find the index of the line that cursor is currently on.
    int pos = Selection.getSelectionEnd(text);
    int line = layout.getLineForOffset(pos);

    // Find the start pos and end pos of that line, and its text.
    int lineStart = layout.getLineStart(line);
    int lineEnd = layout.getLineEnd(line);
    CharSequence lineText = text.subSequence(lineStart, lineEnd);

    // Measure substrings of the line text of increasing lengths until we find the closest
    // to the EditText's center position.
    int centerX = edt.getMeasuredWidth() / 2 - edt.getPaddingLeft();
    TextPaint paint = edt.getPaint();
    float lastWidth = 0;
    for (int i = 1; i < lineText.length(); i++) {
        float width = paint.measureText(lineText, 0, i);
        if (width >= centerX) {
            // We're past the visual center.
            if (centerX - lastWidth < width - centerX) {
                // Turns out the last pos was closest, not this one.
                edt.setSelection(lineStart + i - 1);
            } else {
                // This pos is closest to the center.
                edt.setSelection(lineStart + i);
            }
            return;
        }
        lastWidth = width;
    }

    if (lineText.length() != 0) {
        // Line doesn't reach center, select line end.
        edt.setSelection(lineEnd);
    }  // Otherwise, line was empty, start of the line is already selected.
}

该方法使用TextPaint对文本进行测量,找到距离EditText视觉中心最近的position。 如果线没有到达中心,cursor 会走到线的末端。 理想情况下,您希望在此处执行二进制搜索而不是线性搜索,以快速找到最接近的 position,因为TextPaint.measureText可能是一项昂贵的操作。 例如,如果您打算有数千个字符的行,那可能是最好的。

我希望这能回答您的问题,否则请发表评论。

只需设置 TextAlignment 属性;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM