有一个 android.text.Selection 类允许您在 EditText 中移动光标:
要将光标移动到行的左侧,请使用Selection.moveToLeftEdge(edt.getText(), edt.getLayout())。还有一种方法可以将光标移到当前行的右边。
将光标移动到行的中心有点复杂。首先,您必须确定线条的“中心”是什么意思。例如,如果我们有以下行:
WWWWWWWWWWWWWWWWWWWWWWWWwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
由 25 个大写的 Ws 和 25 个小写的 Ls 组成。在这条线上,中心是在 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 是一个潜在的昂贵操作。例如,如果您打算有数千个字符的行,那可能是最好的。
我希望这能回答您的问题,否则请发表评论。