【问题标题】:PagerTabStrip TalkBack accessibilityPagerTabStrip TalkBack 辅助功能
【发布时间】:2017-01-08 16:32:50
【问题描述】:

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

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

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

  • PagerTabStrip 的子类中使用AccessibilityEvent 为发声提供更多上下文。它不起作用,因为 AccessibilityEvent 中的 getText()getContentDescription 方法不用于发声。
  • ViewPager 处理AccessibilityNodeInfo,看看我能不能解决它。但我还没有确定发声的来源(是标签还是内容),也没有确定 AccessiblityNodeInfo 中必须更改哪些内容才能更改发声。

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

【问题讨论】:

    标签: android accessibility talkback


    【解决方案1】:

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

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

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

    【讨论】:

    • 非常感谢,它成功了!我使用我的 OnPageChangeListener 选择带有 Talkback 的当前选项卡,而不是最后一个已单击的选项卡。我知道 Android TalkBack 用户已经习惯了这种行为,但没有指明什么是可点击的,我想我会等待用户测试 ;-)
    【解决方案2】:

    对于选项卡本身,如果您负责为 View 充气,那么您可以使用自定义 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));
        }
    
    });
    

    我知道 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"

    this answer中给出了自定义使用提示的其他方式。

    【讨论】:

    • 它不读取我的内容。它说:“选定的 tabtitle1 tab 1 of 4”。
    猜你喜欢
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    相关资源
    最近更新 更多