我目前正在处理可能在其文本中包含占位符的多行编辑文本。为了避免修改这些占位符,我在 EditText 小部件中添加了一个 onClickListener,它检查光标位置是否在这样的占位符内。在这种情况下,应选择占位符,以防止除完全删除之外的任何修改。
这在我的 Android 2.3 设备上工作得非常好,但在 Android 4.x 上,选择在 onClick 事件之后被修改,并且光标显示在占位符的开头而没有选择。
在 onClickListener 的源代码下方。
protected void textClickListener(EditText v) {
Pattern p = Pattern.compile(placeholderRegex);
Matcher matcher = p.matcher(v.getText());
int sel_start = v.getSelectionStart();
int sel_end = v.getSelectionEnd();
if (sel_start == -1) {
return;
}
while (matcher.find()) {
int pattern_start = matcher.start();
int pattern_end = pattern_start + 25;
if (pattern_start > sel_end) {
continue;
}
if (pattern_end < sel_start) {
continue;
}
v.setSelection(Math.min(sel_start, pattern_start), Math.max(sel_end, pattern_end));
return;
}
}
此代码工作正常,使用正确的值调用 setSelection 并且实际设置了选择。我在 Selection.setSelection 方法上设置了一个断点,发现它是从 PositionListener 调用的,它是 android.widget.editor 的一个内部类,它将选择长度设置为 0。下面是这个 setSelection 调用的堆栈跟踪:
Selection.setSelection(Spannable, int) line: 87
Editor$InsertionHandleView.updateSelection(int) line: 3271
Editor$InsertionHandleView(Editor$HandleView).positionAtCursorOffset(int, boolean) line: 3045
Editor$InsertionHandleView(Editor$HandleView).updatePosition(int, int, boolean, boolean) line: 3064
Editor$PositionListener.onPreDraw() line: 2047
ViewTreeObserver.dispatchOnPreDraw() line: 671
ViewRootImpl.performTraversals() line: 1820
ViewRootImpl.doTraversal() line: 1000
ViewRootImpl$TraversalRunnable.run() line: 4214
Choreographer$CallbackRecord.run(long) line: 725
Choreographer.doCallbacks(int, long) line: 555
Choreographer.doFrame(long, int) line: 525
Choreographer$FrameDisplayEventReceiver.run() line: 711
Handler.handleCallback(Message) line: 615
Choreographer$FrameHandler(Handler).dispatchMessage(Message) line: 92
Looper.loop() line: 137
ActivityThread.main(String[]) line: 4745
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 511
ZygoteInit$MethodAndArgsCaller.run() line: 786
ZygoteInit.main(String[]) line: 553
NativeStart.main(String[]) line: not available [native method]
任何想法如何防止这种情况或如何在此 PositionListener 操作之后设置选择?