3

我目前正在努力创造PagerTabStrip更多的TalkBack发声。上下文是:

  • 我想在左右选项卡上添加“选项卡 [选项卡名称] 未选中,单击两次以选择”,并将“选项卡 [选项卡名称] 选中”添加到TalkBack用户的中心。
  • 我还想在单击选项卡时添加发声,以警告用户其内容已更改并告诉TalkBack关注中心选项卡。

我已经通过重写所有需要的类(例如:、、、)并直接在选项卡上添加正确的部分成功地PagerTitleStrip做到ViewPager了这FragmentPagerAdapter一点。它工作得很好,但我不满意。这些类的维护需要针对 Android 主类的每个新版本进行更新(或者我将保留旧设计),并且我发现每次都复制粘贴所有类内容很脏(下一个开发人员呢?)。所以,我尝试了另一种方法:contentDescriptionTextView

  • AccessibilityEvent在子类中使用PagerTabStrip为发声提供更多上下文。它不起作用,因为getText()其中getContentDescription的方法AccessibilityEvent不用于发声。
  • 继续努力AccessibilityNodeInfoViewPager看看我能不能解决。但是我还没有确定发声的来源(是标签还是内容),也没有确定AccessiblityNodeInfo要更改发声必须更改的内容。

所以,我想知道是否可以使用子类来解决我的问题,或者我是否别无选择,只能复制主类。在此先感谢您的帮助。

4

2 回答 2

2

这实际上很简单。您要做的是创建 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);
    }

}

请注意,我覆盖了内容描述。通过这种方式,我们不会更改应用程序的任何可视化表示,只会更改对讲读出的内容。

注意:对讲用户习惯于“双击选择”部分。正如我在代码中所做的那样,我将把它关闭。

于 2015-02-12T19:37:50.360 回答
1

对于选项卡本身,如果您负责膨胀视图,那么您可以使用自定义 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>

这预先假设您(或您正在使用的库)在选中时标记选项卡视图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));
    }

});

我知道 Android TalkBack 用户已经习惯了这种行为,但没有指明可点击的内容

正如@ChrisCM 提到的那样,(默认情况下)可点击的元素上有一个指示 - TalkBack 会将“双击激活”(以前的“双击选择”)附加到带有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".

此答案中给出了自定义使用提示的其他方法。

于 2017-01-08T08:24:55.230 回答