gpt4 book ai didi

android - EditText 小部件的 onClickListener 中的 SetSelection 行为很奇怪

转载 作者:行者123 更新时间:2023-11-30 03:55:04 25 4
gpt4 key购买 nike

我目前正在处理一个多行编辑文本,它的文本中可能有占位符。为了避免修改这些占位符,我向 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 操作之后设置选择的任何想法?

最佳答案

迁移自问题

最后我发现,您必须修改 OnTouchListener 中的选择。为了使它变得更加复杂,您必须修改该监听器的两次调用(ACTION_DOWNACTION_UP)中的选择。如果你只做一次(就像我出于性能原因所做的那样),它也不会起作用。所以最终的工作代码是:

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
protected boolean textTouchListener(EditText v, MotionEvent event) {
placeholder_selected = false;
Pattern p = Pattern.compile(placeHolderRegex);
Matcher matcher = p.matcher(v.getText());
int click_position = v.getOffsetForPosition(event.getX(), event.getY());
int sel_start = click_position;
int sel_end = click_position;
if (sel_start == -1) {
return false;
}
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));
placeholder_selected = true;
return true;
}
return false;
}

出于兼容性原因,仍然需要 OnClickListener,因为 getOffsetForPosition 方法不适用于 11 (Honeycomb) 以下的 API 级别。根据使用的 API,只需执行两个监听器之一。

关于android - EditText 小部件的 onClickListener 中的 SetSelection 行为很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13477279/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com