PagerTabStrip TalkBack 辅助功能
PagerTabStrip TalkBack accessibility
我目前正在努力创造 PagerTabStrip
更多 TalkBack
发声。
上下文是:
- 我想在左侧和右侧选项卡上添加 "Tab [tab name] not selected, click twice to select",并为
TalkBack
用户在中间选项卡上添加 "Tab [tab name] selected"。
- 我还想在单击选项卡时添加声音以警告用户其内容已更改并告诉
TalkBack
将焦点放在中心选项卡上。
我已经通过重写所有需要的 classes(例如:PagerTitleStrip
、ViewPager
、FragmentPagerAdapter
)并添加正确的 contentDescription
直接在选项卡 TextView
上。它工作得很好,但我不满意。 classes 的维护需要针对 Android main classes 的每个新版本进行更新(否则我将保留旧设计)并且我发现复制粘贴所有内容很脏class 每次的内容(下一个开发者呢?)。
所以,我尝试了另一种方法:
- 在
PagerTabStrip
的子 class 中使用 AccessibilityEvent
为发声提供更多背景信息。它不起作用,因为 AccessibilityEvent
中的 getText()
和 getContentDescription
方法未用于发声。
- 从
ViewPager
开始 AccessibilityNodeInfo
,看看我能否解决。但是我还没有确定发声的来源(是标签还是内容),也没有确定 AccessiblityNodeInfo
中必须更改什么才能改变发声。
所以,我想知道是否可以使用子class 来解决我的问题,或者我是否别无选择只能复制主classes。
预先感谢您的帮助。
这其实很简单。您要做的是创建 PagerTabStrip 的子类。在这个子类中,增加可访问性事件的传播以添加您想要的信息!下面是我的实现。
public class A11yPagerTabStrip extends PagerTabStrip {
public A11yPagerTabStrip(Context context) {
super(context);
}
public A11yPagerTabStrip(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
Log.wtf(LOG_TAG, "onRequestSendAccessibilityEvent: " + event.toString());
final String textViewTitle = ((TextView) child).getText().toString();
final ViewPager viewPager = (ViewPager) this.getParent();
final int itemIndex = viewPager.getCurrentItem();
String title = viewPager.getAdapter().getPageTitle(itemIndex).toString();
if (textViewTitle.equalsIgnoreCase(title)) {
child.setContentDescription("Tab " + textViewTitle + "selected.");
} else {
child.setContentDescription("Tab " + textViewTitle + "not selected.");
}
return super.onRequestSendAccessibilityEvent(child, event);
}
}
请注意,我覆盖了内容描述。通过这种方式,我们不会更改应用程序的任何视觉表示,只是读出的内容。
注意:对讲用户使用 "double tap to select" 部分。正如我在代码中所做的那样,我会保留它。
对于选项卡本身,如果您负责填充视图,那么您可以使用自定义 TextView,根据其激活(或选择)状态修改其内容描述:
public class TabTextView extends TextView {
public TabTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public CharSequence getContentDescription() {
CharSequence contentDescription = super.getContentDescription();
return isActivated() ? appendSelectedTo(contentDescription) : contentDescription;
}
private String appendSelectedTo(CharSequence contentDescription) {
return getResources().getString(R.string.tab_selected, contentDescription);
}
}
其中 R.string.tab_selected
是 <string name="tab_selected">%1$s selected</string>
这预先假设您(或 the library you're using)在选择时用 setActivated(true)/setSelected(true)
标记选项卡视图(以及用 setActivated(false)/setSelected(false)
标记所有其他选项卡)。
向用户宣布内容已更改的最简单方法是添加一个 ViewPager.OnPageChangeListener
在页面更改时宣布:
viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// TODO: format correctly with String resource to support translation
viewPager.announceForAccessibility("Showing " + viewPager.getAdapter().getPageTitle(position));
}
});
I know Android TalkBack users are used to the behavior without indication on what is clickable
有(默认情况下)关于可点击的元素的指示,正如@ChrisCM 提到的那样 - TalkBack 将附加 "Double Tap to Activate"(以前是 "Double Tap to Select")到附加了 View.OnClickListener
的视图上。
您可以通过覆盖 onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info)
方法来修改 TalkBack 使用辅助功能委托朗读的操作:
class TabAccessibilityDelegate extends AccessibilityDelegateCompat {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.addAction(
new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_CLICK,
"select tab"
)
);
}
}
并在您的每个选项卡视图上设置它:
ViewCompat.setAccessibilityDelegate(tabView, new TabAccessibilityDelegate());
现在 TalkBack 将显示:"<tab content description>... double tap to select tab"
。
自定义使用提示的其他方法在中给出。
我目前正在努力创造 PagerTabStrip
更多 TalkBack
发声。
上下文是:
- 我想在左侧和右侧选项卡上添加 "Tab [tab name] not selected, click twice to select",并为
TalkBack
用户在中间选项卡上添加 "Tab [tab name] selected"。 - 我还想在单击选项卡时添加声音以警告用户其内容已更改并告诉
TalkBack
将焦点放在中心选项卡上。
我已经通过重写所有需要的 classes(例如:PagerTitleStrip
、ViewPager
、FragmentPagerAdapter
)并添加正确的 contentDescription
直接在选项卡 TextView
上。它工作得很好,但我不满意。 classes 的维护需要针对 Android main classes 的每个新版本进行更新(否则我将保留旧设计)并且我发现复制粘贴所有内容很脏class 每次的内容(下一个开发者呢?)。
所以,我尝试了另一种方法:
- 在
PagerTabStrip
的子 class 中使用AccessibilityEvent
为发声提供更多背景信息。它不起作用,因为AccessibilityEvent
中的getText()
和getContentDescription
方法未用于发声。 - 从
ViewPager
开始AccessibilityNodeInfo
,看看我能否解决。但是我还没有确定发声的来源(是标签还是内容),也没有确定AccessiblityNodeInfo
中必须更改什么才能改变发声。
所以,我想知道是否可以使用子class 来解决我的问题,或者我是否别无选择只能复制主classes。 预先感谢您的帮助。
这其实很简单。您要做的是创建 PagerTabStrip 的子类。在这个子类中,增加可访问性事件的传播以添加您想要的信息!下面是我的实现。
public class A11yPagerTabStrip extends PagerTabStrip {
public A11yPagerTabStrip(Context context) {
super(context);
}
public A11yPagerTabStrip(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
Log.wtf(LOG_TAG, "onRequestSendAccessibilityEvent: " + event.toString());
final String textViewTitle = ((TextView) child).getText().toString();
final ViewPager viewPager = (ViewPager) this.getParent();
final int itemIndex = viewPager.getCurrentItem();
String title = viewPager.getAdapter().getPageTitle(itemIndex).toString();
if (textViewTitle.equalsIgnoreCase(title)) {
child.setContentDescription("Tab " + textViewTitle + "selected.");
} else {
child.setContentDescription("Tab " + textViewTitle + "not selected.");
}
return super.onRequestSendAccessibilityEvent(child, event);
}
}
请注意,我覆盖了内容描述。通过这种方式,我们不会更改应用程序的任何视觉表示,只是读出的内容。
注意:对讲用户使用 "double tap to select" 部分。正如我在代码中所做的那样,我会保留它。
对于选项卡本身,如果您负责填充视图,那么您可以使用自定义 TextView,根据其激活(或选择)状态修改其内容描述:
public class TabTextView extends TextView {
public TabTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public CharSequence getContentDescription() {
CharSequence contentDescription = super.getContentDescription();
return isActivated() ? appendSelectedTo(contentDescription) : contentDescription;
}
private String appendSelectedTo(CharSequence contentDescription) {
return getResources().getString(R.string.tab_selected, contentDescription);
}
}
其中 R.string.tab_selected
是 <string name="tab_selected">%1$s selected</string>
这预先假设您(或 the library you're using)在选择时用 setActivated(true)/setSelected(true)
标记选项卡视图(以及用 setActivated(false)/setSelected(false)
标记所有其他选项卡)。
向用户宣布内容已更改的最简单方法是添加一个 ViewPager.OnPageChangeListener
在页面更改时宣布:
viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
// TODO: format correctly with String resource to support translation
viewPager.announceForAccessibility("Showing " + viewPager.getAdapter().getPageTitle(position));
}
});
I know Android TalkBack users are used to the behavior without indication on what is clickable
有(默认情况下)关于可点击的元素的指示,正如@ChrisCM 提到的那样 - TalkBack 将附加 "Double Tap to Activate"(以前是 "Double Tap to Select")到附加了 View.OnClickListener
的视图上。
您可以通过覆盖 onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info)
方法来修改 TalkBack 使用辅助功能委托朗读的操作:
class TabAccessibilityDelegate extends AccessibilityDelegateCompat {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
info.addAction(
new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
AccessibilityNodeInfoCompat.ACTION_CLICK,
"select tab"
)
);
}
}
并在您的每个选项卡视图上设置它:
ViewCompat.setAccessibilityDelegate(tabView, new TabAccessibilityDelegate());
现在 TalkBack 将显示:"<tab content description>... double tap to select tab"
。
自定义使用提示的其他方法在