From b9d3743cda95d1f475dbec8f6d72935941519deb Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Sun, 24 Feb 2019 19:21:59 -0800 Subject: [PATCH] add talkback navigation support for links and header (#22447) Summary: 1. add role description for heading 2. add talkback navigation support for link and header Fixes #22440 Pull Request resolved: https://github.com/facebook/react-native/pull/22447 Differential Revision: D14205822 Pulled By: cpojer fbshipit-source-id: 86bfc3bfc851f3544b1962012abaf8d1a357a9d2 --- .../js/AccessibilityAndroidExample.android.js | 25 +++++++++++++++++++ .../uimanager/AccessibilityDelegateUtil.java | 24 +++++++++++++++++- .../res/views/uimanager/values/strings.xml | 4 +++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/RNTester/js/AccessibilityAndroidExample.android.js b/RNTester/js/AccessibilityAndroidExample.android.js index ac4b6c00108667..aa41b63a122f2d 100644 --- a/RNTester/js/AccessibilityAndroidExample.android.js +++ b/RNTester/js/AccessibilityAndroidExample.android.js @@ -111,6 +111,31 @@ class AccessibilityAndroidExample extends React.Component { + + + This is + + nontouchable accessible view with label. + + + + + + + ToastAndroid.show('Toasts work by default', ToastAndroid.SHORT) + } + accessibilityRole="link"> + + Click me + Or not + + + + diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/AccessibilityDelegateUtil.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/AccessibilityDelegateUtil.java index 617773b24eb0fc..aeffe238a91ba8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/AccessibilityDelegateUtil.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/AccessibilityDelegateUtil.java @@ -9,6 +9,9 @@ import android.support.v4.view.AccessibilityDelegateCompat; import android.support.v4.view.ViewCompat; import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat; +import android.text.SpannableString; +import android.text.style.URLSpan; import android.view.View; import com.facebook.react.R; import java.util.Locale; @@ -98,7 +101,6 @@ public static void setDelegate(final View view) { public void onInitializeAccessibilityNodeInfo( View host, AccessibilityNodeInfoCompat info) { super.onInitializeAccessibilityNodeInfo(host, info); - setRole(info, accessibilityRole, view.getContext()); if (!(accessibilityHint == null)) { String contentDescription=(String)info.getContentDescription(); if (contentDescription != null) { @@ -108,6 +110,8 @@ public void onInitializeAccessibilityNodeInfo( info.setContentDescription(accessibilityHint); } } + + setRole(info, accessibilityRole, view.getContext()); } }); } @@ -127,6 +131,18 @@ public static void setRole(AccessibilityNodeInfoCompat nodeInfo, AccessibilityRo if (Locale.getDefault().getLanguage().equals(new Locale("en").getLanguage())) { if (role.equals(AccessibilityRole.LINK)) { nodeInfo.setRoleDescription(context.getString(R.string.link_description)); + + if (nodeInfo.getContentDescription() != null) { + SpannableString spannable = new SpannableString(nodeInfo.getContentDescription()); + spannable.setSpan(new URLSpan(""), 0, spannable.length(), 0); + nodeInfo.setContentDescription(spannable); + } + + if (nodeInfo.getText() != null) { + SpannableString spannable = new SpannableString(nodeInfo.getText()); + spannable.setSpan(new URLSpan(""), 0, spannable.length(), 0); + nodeInfo.setText(spannable); + } } if (role.equals(AccessibilityRole.SEARCH)) { nodeInfo.setRoleDescription(context.getString(R.string.search_description)); @@ -140,6 +156,12 @@ public static void setRole(AccessibilityNodeInfoCompat nodeInfo, AccessibilityRo if (role.equals(AccessibilityRole.ADJUSTABLE)) { nodeInfo.setRoleDescription(context.getString(R.string.adjustable_description)); } + if (role.equals(AccessibilityRole.HEADER)) { + nodeInfo.setRoleDescription(context.getString(R.string.header_description)); + final AccessibilityNodeInfoCompat.CollectionItemInfoCompat itemInfo = + AccessibilityNodeInfoCompat.CollectionItemInfoCompat.obtain(0, 1, 0, 1, true); + nodeInfo.setCollectionItemInfo(itemInfo); + } } if (role.equals(AccessibilityRole.IMAGEBUTTON)) { nodeInfo.setClickable(true); diff --git a/ReactAndroid/src/main/res/views/uimanager/values/strings.xml b/ReactAndroid/src/main/res/views/uimanager/values/strings.xml index 60c9e805311896..d180d2a703b5f4 100644 --- a/ReactAndroid/src/main/res/views/uimanager/values/strings.xml +++ b/ReactAndroid/src/main/res/views/uimanager/values/strings.xml @@ -20,4 +20,8 @@ name="adjustable_description" translatable="false" >Adjustable + Heading