[英]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.