首先,我已经阅读了关于这个问题的其他问题,但我正在尝试一些不同的东西。
我有一个多行EditText,如下图所示。
<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"
/>
我想做的是当点击一个菜单项时,将光标设置在行的中心或行的左边(在多行EditText中)。因此,当我点击一个菜单项时,我想让光标移动到EditText中当前行的中心位置。当我按下另一个菜单项时,我需要光标移动到当前行的左边(所有的菜单项总是显示在工具栏上)。
有什么方法可以做到这一点吗?
我试过用 scriptET.setGravity(Gravity.CENTER);
(其中 scriptET
是对我的EditText的引用),但是什么都没有发生。
EDIT: 使用评论中的建议,我设法将光标设置为左边,用 Selection.moveToLeftEdge(scriptET.getText(), scriptET.getLayout());
. 通过使用一些Toasts信息,我注意到 getLayout()
方法给出的是null,但点击时光标还是会移动到当前行的左边。
另外,当行为空时,在 "逻辑 "中心移动光标是不可能的,我真的需要这样做。
任何建议都非常感谢!
有一个 android.text.Selection
类,它允许你在一个EditText中移动光标。
要将光标移动到该行的左边,使用 Selection.moveToLeftEdge(edt.getText(), edt.getLayout())
. 还有一种方法可以将光标移动到当前行的右边。
将光标移动到行的中心是比较复杂的。首先,你必须决定你所说的 "中心 "是什么意思。例如,如果我们有以下一行。
由25个大写字母W和25个小写字母L组成。在这条线中,中心是在Ws和Ls的交界处(位置25),还是在Ws块的某个地方?我们称前者为 "逻辑 "中心,后者为 "视觉 "中心。
下面是一个将光标移动到逻辑中心的方法。
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);
}
这里是一个将光标移动到视觉中心的方法。
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视觉中心的位置。如果行没有到达中心,光标就会移动到行的末端。理想情况下,你会希望在这里进行二进制搜索,而不是线性搜索,以快速找到最接近的位置,这是因为 TextPaint.measureText
是一个潜在的昂贵操作。例如如果你打算有几千个字符的行,可能是最好的。
我希望这能回答你的问题,否则请留言。
只要设置TextAlignment属性。