我知道在TextView
的xml中设置android:textIsSelectable="true"
会显示原生文本选择弹出窗口,我一直在应用程序中使用它。但是,当我尝试在附加到RecyclerView
的视图中设置相同的属性时,我发现它不再起作用。每当我尝试选择文本时,都会出现以下日志-
TextView: TextView does not support text selection. Action mode cancelled.
我不知道为什么?为什么它能在其他屏幕上工作,而不能在RecyclerView
上工作。我读了很多帖子-
TextView with android:textIsSelectable="true" not working in listview
textview textIsSelectable="true" not working in Listview
android:textIsSelectable="true" for TextView inside Listview does not work
但后来我遇到了这个帖子-
Android: "TextView does not support text selection. Action mode cancelled"
@hungkk
的回复对我很有效。他的解决方案建议将TextView
宽度从match_parent
更改为wrap_content
。
我知道我可以做到这一点,但我的问题是它是如何解决这个问题的,因为它对我来说看起来很奇怪。另外,如果我想保持宽度为match_parent
,该如何解决呢?
欢迎任何意见。
发布于 2017-06-20 16:00:09
在recyclerview的main-parent布局中添加属性
android:descendantFocusability="beforeDescendants"
然后在rowitem布局的TextView中添加
android:textIsSelectable="true"
发布于 2019-05-21 00:24:17
我发现RecyclerView中的TextView可以第一次选择,但是当ViewHolder被回收或适配器notifyDataSetChanged时,所有的文本视图将不能被选择。我发现这个解决方案对我很有效。
yourTextView.setText("your text");
yourTextView.setTextIsSelectable(false);
yourTextView.measure(-1, -1);//you can specific other values.
yourTextView.setTextIsSelectable(true);
为什么要这样做?因为我已经调试过,在android源代码中发现了一些逻辑:
TextView.java:
public void setTextIsSelectable(boolean selectable) {
if (!selectable && mEditor == null) return; // false is default value with no edit data
createEditorIfNeeded();
if (mEditor.mTextIsSelectable == selectable) return;
mEditor.mTextIsSelectable = selectable;
setFocusableInTouchMode(selectable);
setFocusable(FOCUSABLE_AUTO);
setClickable(selectable);
setLongClickable(selectable);
// mInputType should already be EditorInfo.TYPE_NULL and mInput should be null
setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
setText(mText, selectable ? BufferType.SPANNABLE : BufferType.NORMAL);
// Called by setText above, but safer in case of future code changes
mEditor.prepareCursorControllers();
}
Editor.java
void prepareCursorControllers() {
boolean windowSupportsHandles = false;
ViewGroup.LayoutParams params = mTextView.getRootView().getLayoutParams();
if (params instanceof WindowManager.LayoutParams) {
WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
windowSupportsHandles = windowParams.type < WindowManager.LayoutParams.FIRST_SUB_WINDOW
|| windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
}
boolean enabled = windowSupportsHandles && mTextView.getLayout() != null;
mInsertionControllerEnabled = enabled && isCursorVisible();
**mSelectionControllerEnabled = enabled && mTextView.textCanBeSelected();**
if (!mInsertionControllerEnabled) {
hideInsertionPointCursorController();
if (mInsertionPointCursorController != null) {
mInsertionPointCursorController.onDetached();
mInsertionPointCursorController = null;
}
}
if (!mSelectionControllerEnabled) {
stopTextActionMode();
if (mSelectionModifierCursorController != null) {
mSelectionModifierCursorController.onDetached();
mSelectionModifierCursorController = null;
}
}
}
-> TextView.java
/**
* Test based on the <i>intrinsic</i> charateristics of the TextView.
* The text must be spannable and the movement method must allow for arbitary selection.
*
* See also {@link #canSelectText()}.
*/
boolean textCanBeSelected() {
// prepareCursorController() relies on this method.
// If you change this condition, make sure prepareCursorController is called anywhere
// the value of this condition might be changed.
if (mMovement == null || !mMovement.canSelectArbitrarily()) return false;
return isTextEditable()
|| (isTextSelectable() && mText instanceof Spannable && isEnabled());
}
您可以在Emulator中调试并跟踪此代码。
发布于 2017-06-19 17:41:13
如果在recyclerview
或listview
中添加android:descendantFocusability="blocksDescendants"
,则将其删除。检查完这个之后
https://stackoverflow.com/questions/36801486
复制相似问题