Как изменить инструкции Android для двухстороннего и длительного нажатия

У меня есть представление, которое имеет длинный обработчик нажатий. Я использую описание содержимого, чтобы установить сообщение, которое говорит Talkback, когда представление получает фокус.

В настоящее время он говорит, что мое описание контента сразу после получения фокуса, и после небольшой паузы говорит:

Дважды нажмите, чтобы активировать, дважды нажмите и удерживайте для длительного нажатия

Я хочу изменить это сообщение на что-то вроде

Дважды нажмите "Действие 1", дважды нажмите и удерживайте "Действие 2"

Есть ли способ сделать это?

Я смотрел в onPopulateAccessibilityEvent(), это становится TYPE_VIEW_ACCESSIBILITY_FOCUSED событие, но я не смог изменить нужное сообщение.

Я что-то упустил?

5 ответов

Решение

В API 21+ вы можете настраивать имена действий, настраивая настраиваемые действия в своих представлениях. AccessibilityNodeInfo, Есть два подхода к этому: 1) установить AccessibilityDelegate и переопределить onInitializeAccessibilityNodeInfo метод делегата или 2) расширить класс представления и переопределить onInitializeAccessibilityNodeInfo,

В любом случае вы будете создавать новый AccessibilityAction и устанавливать его на узле, используя AccessibilityNodeInfo.addAction.

Если вы решили использовать делегата, вы должны задать пользовательское описание для действия щелчка следующим образом:

view.setAccessibilityDelegate(new AccessibilityDelegate() {
  @Override
  public void onInitializeAccessibilityNodeInfo(
      View v, AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(v, info);

    // A custom action description. For example, you could use "pause"
    // to have TalkBack speak "double-tap to pause."
    CharSequence description = getResources().getText(R.string.my_click_desc);
    AccessibilityAction customClick = new AccessibilityAction(
            AccessibilityAction.ACTION_ACTION_CLICK, description);
    info.addAction(customClick);
  }
});

Если ваше приложение предназначено для API < 21, подставьте соответствующее *Compat поддержка библиотечных методов. Функция не перенесена обратно, поэтому вы не получите пользовательских описаний API < 21, но сможете избежать явных проверок версий в коде приложения.

Похоже на то AccessibilityAction немного изменился с тех пор, как alanv опубликовал свой ответ. Вот рабочее решение с использованием ViewCompat:

ViewCompat.setAccessibilityDelegate(view, new AccessibilityDelegateCompat() {
    @Override
    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
        super.onInitializeAccessibilityNodeInfo(host, info);
        // A custom action description. For example, you could use "pause"
        // to have TalkBack speak "double-tap to pause."
        CharSequence description = host.getResources().getText(R.string.my_click_desc);
        AccessibilityActionCompat customClick = new AccessibilityActionCompat(
                    AccessibilityNodeInfoCompat.ACTION_CLICK, description);
        info.addAction(customClick);
    }
});

Используйте код ниже для тех, кто хочет удалить всю фразу т.е. "дважды нажмите, чтобы активировать", "дважды нажмите и удерживайте для длительного нажатия".

mSubTitleText = (TextView) view.findViewById(R.id.txt_subtitle);

 ViewCompat.setAccessibilityDelegate(mSubTitleText, new AccessibilityDelegateCompat() {
            @Override
            public void onPopulateAccessibilityEvent(View host, AccessibilityEvent event) {
                host.setClickable(false);
                host.setLongClickable(false);
            }
        });

Используйте код ниже для тех, кто хочет удалить всю фразу т.е. "дважды нажмите на".

ViewCompat.setAccessibilityDelegate(view, new AccessibilityDelegateCompat() {
        @Override
        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
            super.onInitializeAccessibilityNodeInfo(host, info);
            info.addAction(AccessibilityNodeInfoCompat.ACTION_FOCUS);
        }
});

Это в основном вызывает код ниже и requestFocus не имеет никакого связанного с ним объявления по умолчанию.

case AccessibilityNodeInfo.ACTION_FOCUS: {
                if (!hasFocus()) {
                    // Get out of touch mode since accessibility
                    // wants to move focus around.
                    getViewRootImpl().ensureTouchMode(false);
                    return requestFocus();
                }
            }

Вот один образец:

      ViewCompat.setAccessibilityDelegate(set_actions_button, object : AccessibilityDelegateCompat() {
    override fun onInitializeAccessibilityNodeInfo(v: View, info: AccessibilityNodeInfoCompat) {
        super.onInitializeAccessibilityNodeInfo(v, info)
        info.addAction(AccessibilityActionCompat(
            AccessibilityNodeInfoCompat.ACTION_CLICK, "Edit note"))
        info.addAction(AccessibilityActionCompat(
            AccessibilityNodeInfoCompat.ACTION_LONG_CLICK, "Copy note"))
    }
})

Взгляните на эту статью, которая очень хорошо объясняет.

Другие вопросы по тегам