Skip to content

Commit 0093b32

Browse files
joevilchesfacebook-github-bot
authored andcommitted
Allow text links to be navigatable via keyboard by default (facebook#48773)
Summary: This diff contains 2 fixes with regards to clickable text accessibility on Android. 1. It allows nested `Text` links to be accessible via keyboard. The accessibility here is a bit unique. The clickable text is not focused in the classical since that Android provides on `View`s (after all, the part being focused is not even a `TextView`. Its a `Span` in a `TextView`). However, it is [selected](https://developer.android.com/reference/android/widget/TextView#setSelected(boolean)), and pressing enter while it is selected will press the text, so for all intents and purposes it is focused. Some quirks here, though, are that you cannot press tab to cycle through the links in text, you have to use arrow keys. And the arrow keys no longer let you move around to the next item (as they are stuck being used to navigate the links). I *could* override this behavior but I do not see much of a point as long as one can actually get to everything on screen in a semi-logical way. Anyway, the fix here is using [`LinkMovementMethod`](https://developer.android.com/reference/android/text/method/LinkMovementMethod) to navigate between clickable spans, which is exactly what that class exists for. Note that I override this class so that touching the links does not actually highlight them like you see in the videos. 2. In the case we state update and remove the "click-ability" of the text, this diff makes it so that Explore By Touch no longer can focus on the link. The code was in the same area so I decided to just lump that together :P Changelog: [Android] [Fixed] - Allow text links to be navigable via keyboard by default Differential Revision: D68306316
1 parent 9afad52 commit 0093b32

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
package com.facebook.react.views.text
9+
10+
import android.text.Selection
11+
import android.text.Spannable
12+
import android.text.method.LinkMovementMethod
13+
import android.view.MotionEvent
14+
import android.widget.TextView
15+
16+
internal object ReactLinkMovementMethod : LinkMovementMethod() {
17+
override fun onTouchEvent(widget: TextView, buffer: Spannable, event: MotionEvent): Boolean {
18+
val result = super.onTouchEvent(widget, buffer, event)
19+
Selection.removeSelection(buffer)
20+
return result
21+
}
22+
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ public void updateExtraData(ReactTextView view, Object extraData) {
9393
if (update.containsImages()) {
9494
TextInlineImageSpan.possiblyUpdateInlineImageSpans(spannable, view);
9595
}
96-
view.setText(update);
9796

9897
// If this text view contains any clickable spans, set a view tag and reset the accessibility
9998
// delegate so that these can be picked up by the accessibility system.
@@ -106,7 +105,16 @@ public void updateExtraData(ReactTextView view, Object extraData) {
106105
new ReactAccessibilityDelegate.AccessibilityLinks(clickableSpans, spannable));
107106
ReactAccessibilityDelegate.resetDelegate(
108107
view, view.isFocusable(), view.getImportantForAccessibility());
108+
// To enable navigation via keyboard, which is distinct from accessibility navigation.
109+
view.setMovementMethod(ReactLinkMovementMethod.INSTANCE);
110+
} else {
111+
view.setMovementMethod(null);
112+
view.setTag(R.id.accessibility_links, null);
113+
ReactAccessibilityDelegate.resetDelegate(
114+
view, view.isFocusable(), view.getImportantForAccessibility());
109115
}
116+
117+
view.setText(update);
110118
}
111119
}
112120

0 commit comments

Comments
 (0)