From 955cce6e0b72fe6b3037a885a555bc841d112e08 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Wed, 28 Nov 2018 20:27:12 +0800 Subject: [PATCH] add talkback navigation for links and header 1. add role description for heading 2. add talkback navigation support for link and header --- .../uimanager/AccessibilityDelegateUtil.java | 27 ++++++++++++++++++- .../res/views/uimanager/values/strings.xml | 4 +++ 2 files changed, 30 insertions(+), 1 deletion(-) 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..a2a34ac512b5e4 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,15 @@ 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