Status Update
Comments
a....@gmail.com <a....@gmail.com> #2
a....@gmail.com <a....@gmail.com> #3
al...@android.com <al...@android.com> #4
yb...@google.com <yb...@google.com> #5
You should manually persist it per item and restore when item is re-bound.
You can also consider persisting saved state of each item. RecyclerView does not do this automatically because it is an expensive operation and generally unnecessary for a collection view.
a....@gmail.com <a....@gmail.com> #6
And in logs next message is appear after each try to apply selection:
[TextView] TextView does not support text selection. Action mode cancelled.
a....@gmail.com <a....@gmail.com> #7
yb...@google.com <yb...@google.com> #8
al...@android.com <al...@android.com>
li...@gmail.com <li...@gmail.com> #9
"TextView does not support text selection. Selection cancelled."
I see the wording has been changed:
but the issue is the same.
This is an oldie but a goodie. I remember running into this
Looking into workarounds :)
li...@gmail.com <li...@gmail.com> #10
Here's a super simple repro project. Launch the app and fling to the bottom. All the TextViews in the list will exhibit the issue (long pressing on them doesn't select text, and logs the error message).
Seems like it's related to calling setText() multiple times. The issue doesn't happen if you set the text in XML, no matter how much you fling, so it's not purely related to view re-use or re-attachment.
li...@gmail.com <li...@gmail.com> #11
In your adapter, put
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
holder.textView.setEnabled(false);
holder.textView.setEnabled(true);
}
I admit it doesn't look like much, but you can test it on the minimal reproduction I uploaded above -- it really does fix the problem. You can also subclass TextView if that's easier.
Credit to the original commenter on this SO post:
[Deleted User] <[Deleted User]> #13
[Deleted User] <[Deleted User]> #14
ro...@google.com <ro...@google.com>
[Deleted User] <[Deleted User]> #15
[Deleted User] <[Deleted User]> #16
[Deleted User] <[Deleted User]> #17
al...@gmail.com <al...@gmail.com> #18
ma...@gmail.com <ma...@gmail.com> #19
pa...@gmail.com <pa...@gmail.com> #20
[Deleted User] <[Deleted User]> #21
al...@gmail.com <al...@gmail.com> #22
lo...@gmail.com <lo...@gmail.com> #23
Duplicate of a private issue. GOOGLE, WTF!! (What a Terrible Failure!!)
to...@google.com <to...@google.com>
ub...@gmail.com <ub...@gmail.com> #24
Any updates on that?
fa...@gmail.com <fa...@gmail.com> #25
Turn match_parent to wrap_content for the textView seems work. Maybe wrap_content causes request layout and then it works.
[Deleted User] <[Deleted User]> #26
qu...@getaround.com <qu...@getaround.com> #27
do...@gmail.com <do...@gmail.com> #28
pe...@gmail.com <pe...@gmail.com> #29
pa...@hubspot.com <pa...@hubspot.com> #30
I wrote up an issue with my findings to React Native
The Editor
class, responsible for enabling text selection in Android, during its prepareCursorControllers
phase attempts to access the root view from the TextView
. On normal text views (i.e. not mounted in a recycler view), the root view is mounted with layout parameters. On text views mounted by a recycler view, the root view has null layout parameters. Subsequently, the check to ensure that the window can handle selections fails and the Editor
sets its internal mSelectionControllerEnabled
property to false.
The Editor
has a performLongClick
handler where normal selection events would fire. Towards the tail end of the function's implementation, it tries to call selectCurrentWordAndStartDrag
. The third check, checkField
, returns false because its call to canSelectText
returns false. The canSelectText
function is checking for that aforementioned mSelectionControllerEnabled
property. This is what causes the debug warning to fire "TextView does not support text selection. Selection cancelled."
So why does firing setTextIsSelectable
first with false, then true, work? There's a check within every TextView
that sees if it's internal reference to the Editor
mEditor
and the given selectable
property match. Sure enough, they do! So the function returns early and doesn't execute mEditor.prepareCursorControllers
. But by flipping the selectable property to false, we end up falling through the entire function to execute prepareCursorControllers
. By this point, we know the view has properly been attached to a window and not to the ephemeral RecyclerView
, so executing that function should re-enable the selection controller.
It's the same reason why the solution linked in setEnabled
instead of setTextIsSelectable
--that function also executes prepareCursorControllers
. We could call setText
too, or setMovementMode
, but setTextIsSelectable
felt like the leanest, safest way to do it.
TL;DR: if one of y'all could add a prepareCursorControllers
call inside the onAttachedToWindow
method for Editor
, that'd be great thanks!
to...@repsly.com <to...@repsly.com> #31
Reproducable on Android 14, Samsung S23. RecyclerView + Edittexts. Everything works fine on init. After scroll, text selection stops working.
I guess I should try the provided workaround here (thanks people!) if Google isn't providing any fix for this.
Description
[TextView] TextView does not support text selection. Action mode cancelled.
This issue is reproducible in Android KitKat and Marshmallow, but in Lollipop all is ok.