From 8e5eb6389f46d5c6beab2a31c0cdad8f17fd6bc4 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 ac4b6c00108..aa41b63a122 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 617773b24eb..aeffe238a91 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.content.Context; 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 class AccessibilityDelegateUtil { 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 class AccessibilityDelegateUtil { info.setContentDescription(accessibilityHint); } } + + setRole(info, accessibilityRole, view.getContext()); } }); } @@ -127,6 +131,18 @@ public class AccessibilityDelegateUtil { 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 class AccessibilityDelegateUtil { 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 60c9e805311..d180d2a703b 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