Benutzerdefinierte Ansichten barrierefreier gestalten

Wenn für Ihre Anwendung ein „Custom View“-Komponente müssen Sie die Ansicht barrierefreier gestalten. Mit den folgenden Schritten können Sie die Barrierefreiheit, wie auf dieser Seite beschrieben:

  • Klicks auf Richtungscontroller verarbeiten.
  • Implementieren Sie Accessibility API-Methoden.
  • AccessibilityEvent senden für Ihre benutzerdefinierte Ansicht spezifisch sind.
  • Füllen Sie AccessibilityEvent und AccessibilityNodeInfo für Ihre Ansicht.

Klicks auf Richtungscontroller verarbeiten

Auf den meisten Geräten wird beim Klicken auf eine Ansicht mit einem Richtungscontroller eine KeyEvent mit KEYCODE_DPAD_CENTER die aktuell im Fokus ist. Handle (alle Standard-Android-Ansichten) Entsprechend KEYCODE_DPAD_CENTER. Wenn Sie eine benutzerdefinierte View Bedienelement, muss dieses Ereignis denselben Effekt haben wie das Tippen auf die Ansicht auf dem Touchscreen.

Ihr benutzerdefiniertes Steuerelement muss die KEYCODE_ENTER dasselbe Ereignis wie KEYCODE_DPAD_CENTER. Dadurch sind Interaktionen mit einer vollständigen Tastatur möglich. einfacher ist.

<ph type="x-smartling-placeholder">

Accessibility API-Methoden implementieren

Bedienungshilfen-Ereignisse sind Meldungen über die Interaktionen mit der visuellen Benutzeroberfläche Ihrer App Komponenten. Diese Nachrichten werden von Bedienungshilfen verarbeitet, die die Informationen aus diesen Ereignissen nutzen, um zusätzliches Feedback und zusätzliche Aufforderungen zu formulieren. Die Zugänglichkeits- sind Teil der View- und View.AccessibilityDelegate Klassen. Folgende Methoden stehen zur Verfügung:

dispatchPopulateAccessibilityEvent()
Das System ruft diese Methode auf, wenn Ihre benutzerdefinierte Ansicht ein Bedienungshilfen-Ereignis generiert. Standardeinstellung Die Implementierung dieser Methode ruft onPopulateAccessibilityEvent() für diese Ansicht auf und dann die dispatchPopulateAccessibilityEvent()-Methode für jedes untergeordnete Element dieser Ansicht.
onInitializeAccessibilityEvent()
Das System ruft diese Methode auf, um zusätzliche Informationen zum Status der Ansicht zu erhalten. Textinhalt. Wenn Ihre benutzerdefinierte Ansicht eine interaktive Steuerung bietet, die über eine einfache TextView oder Button, diese Methode überschreiben und legen Sie zusätzliche Informationen zu Ihrer Ansicht fest, z. B. Passwortfeldtyp, Kontrollkästchen. oder Bundesstaaten, die Nutzerinteraktionen oder Feedback zum Ereignis ermöglichen. . Wenn Sie diese Methode überschreiben, rufen Sie ihre Superimplementierung auf und ändern Sie nur die Eigenschaften die nicht von der Super-Klasse festgelegt werden.
onInitializeAccessibilityNodeInfo()
Diese Methode liefert Bedienungshilfen Informationen zum Status der Ansicht. Die Die standardmäßige View-Implementierung verfügt über einen Standardsatz von Ansichtseigenschaften. bietet die benutzerdefinierte Ansicht eine interaktive Steuerung über TextView oder Button, überschreiben Sie diese Methode und legen Sie die zusätzlichen Informationen zu Ihrer Ansicht fest. in das AccessibilityNodeInfo-Objekt einfügen, das von dieser Methode verarbeitet wird.
onPopulateAccessibilityEvent()
Mit dieser Methode wird der Prompt für den gesprochenen Text von AccessibilityEvent für Ihr Ansicht. Sie wird auch genannt, wenn die Ansicht einer Ansicht untergeordnet ist, die eine Barrierefreiheit . <ph type="x-smartling-placeholder">
onRequestSendAccessibilityEvent()
Das System ruft diese Methode auf, wenn ein untergeordnetes Element Ihrer Ansicht ein AccessibilityEvent. In diesem Schritt können die Bedienungshilfen in der Elternansicht angepasst werden. mit zusätzlichen Informationen. Implementieren Sie diese Methode nur, wenn Ihre benutzerdefinierte Ansicht folgende Elemente enthalten kann: und ob die übergeordnete Ansicht Kontextinformationen zur Ereignis, das für Bedienungshilfen nützlich ist.
sendAccessibilityEvent()
Das System ruft diese Methode auf, wenn ein Nutzer eine Aktion für eine Datenansicht ausführt. Das Ereignis ist klassifiziert mit einen Nutzeraktionstyp, z. B. TYPE_VIEW_CLICKED. Im Allgemeinen müssen Sie eine AccessibilityEvent, wenn sich der Inhalt Ihrer benutzerdefinierten Ansicht ändert.
sendAccessibilityEventUnchecked()
Diese Methode wird verwendet, wenn der aufrufende Code die Prüfung auf Bedienungshilfe muss auf dem Gerät aktiviert sein (AccessibilityManager.isEnabled()) Wenn Sie diese Methode implementieren, führen Sie den Aufruf so aus, als wäre die Barrierefreiheit aktiviert, unabhängig vom Systemeinstellungen. Normalerweise müssen Sie diese Methode für eine benutzerdefinierte Ansicht nicht implementieren.

Um die Barrierefreiheit zu unterstützen, überschreiben und implementieren Sie die vorherigen Bedienungshilfen direkt in Ihrer benutzerdefinierten Ansichtsklasse.

Implementieren Sie mindestens die folgenden Bedienungshilfen für Ihre Klasse für die benutzerdefinierte Ansicht:

  • dispatchPopulateAccessibilityEvent()
  • onInitializeAccessibilityEvent()
  • onInitializeAccessibilityNodeInfo()
  • onPopulateAccessibilityEvent()

Weitere Informationen zur Implementierung dieser Methoden finden Sie im Abschnitt über zum Ausfüllen von Bedienungshilfen.

Bedienungshilfen-Ereignisse senden

Je nach den Vorgaben Ihrer benutzerdefinierten Ansicht muss diese möglicherweise AccessibilityEvent-Objekte zu unterschiedlichen Zeiten oder für Ereignisse, die nicht standardmäßig verarbeitet werden Implementierung. Die Klasse View bietet eine Standardimplementierung für diese Ereignisse Typen:

<ph type="x-smartling-placeholder">

Im Allgemeinen müssen Sie ein AccessibilityEvent senden, wenn der Inhalt Ihrer benutzerdefinierten Änderungen ansehen. Wenn Sie beispielsweise einen benutzerdefinierten Schieberegler implementieren, durch Drücken der Nach-links- oder Nach-rechts-Taste eingeben, muss Ihre benutzerdefinierte Ansicht das Ereignis TYPE_VIEW_TEXT_CHANGED wenn sich der Schiebereglerwert ändert. Im folgenden Codebeispiel wird die Verwendung des sendAccessibilityEvent()-Methode zum Melden dieses Ereignisses.

Kotlin

override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
    return when(keyCode) {
        KeyEvent.KEYCODE_DPAD_LEFT -> {
            currentValue--
            sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED)
            true
        }
        ...
    }
}

Java

@Override
public boolean onKeyUp (int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
        currentValue--;
        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
        return true;
    }
    ...
}

Ereignisse für Bedienungshilfen ausfüllen

Für jede AccessibilityEvent gibt es eine Reihe erforderlicher Attribute, die die aktuelle Status der Ansicht. Zu diesen Eigenschaften gehören beispielsweise der Klassenname der Ansicht, der Inhalt die Beschreibung und den Status „Geprüft“. Die spezifischen Eigenschaften, die für jeden Ereignistyp erforderlich sind, werden beschrieben. in der AccessibilityEvent in der Referenzdokumentation.

Die View-Implementierung stellt Standardwerte für diese erforderlichen Eigenschaften. Viele dieser Werte, einschließlich Klassenname und Ereigniszeitstempel, automatisch bereitgestellt. Wenn Sie eine benutzerdefinierte Ansichtskomponente erstellen, müssen Sie Informationen zur und Merkmale des Aufrufs. Diese Informationen können auch einfach eine Schaltfläche sein, und kann zusätzliche Statusinformationen enthalten, die Sie dem Ereignis hinzufügen möchten.

Verwenden Sie die Methode onPopulateAccessibilityEvent() und onInitializeAccessibilityEvent() , um die Informationen in einem AccessibilityEvent auszufüllen oder zu ändern. Verwenden Sie die Methode onPopulateAccessibilityEvent()-Methode speziell zum Hinzufügen oder Ändern des Textes Inhalt des Ereignisses, der von Bedienungshilfen wie Bedienungshilfen in hörbare Aufforderungen umgewandelt wird. TalkBack Verwenden Sie die Methode onInitializeAccessibilityEvent(), um zusätzliche Informationen über das Ereignis, wie z. B. den Auswahlstatus der Ansicht.

Implementieren Sie darüber hinaus die onInitializeAccessibilityNodeInfo() . Bedienungshilfen verwenden die AccessibilityNodeInfo-Objekte, die über dieses Feld ausgefüllt sind Methode zur Untersuchung der Ansichtshierarchie, die ein Bedienungshilfen-Ereignis nach dem Empfang generiert. und geben den Nutzenden angemessenes Feedback.

Das folgende Codebeispiel zeigt, wie Sie diese drei Methoden in Ihrer Ansicht überschreiben:

Kotlin

override fun onPopulateAccessibilityEvent(event: AccessibilityEvent?) {
    super.onPopulateAccessibilityEvent(event)
    // Call the super implementation to populate its text for the
    // event. Then, add text not present in a super class.
    // You typically only need to add the text for the custom view.
    if (text?.isNotEmpty() == true) {
        event?.text?.add(text)
    }
}

override fun onInitializeAccessibilityEvent(event: AccessibilityEvent?) {
    super.onInitializeAccessibilityEvent(event)
    // Call the super implementation to let super classes
    // set appropriate event properties. Then, add the new checked
    // property that is not supported by a super class.
    event?.isChecked = isChecked()
}

override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo?) {
    super.onInitializeAccessibilityNodeInfo(info)
    // Call the super implementation to let super classes set
    // appropriate info properties. Then, add the checkable and checked
    // properties that are not supported by a super class.
    info?.isCheckable = true
    info?.isChecked = isChecked()
    // You typically only need to add the text for the custom view.
    if (text?.isNotEmpty() == true) {
        info?.text = text
    }
}

Java

@Override
public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
    super.onPopulateAccessibilityEvent(event);
    // Call the super implementation to populate its text for the
    // event. Then, add the text not present in a super class.
    // You typically only need to add the text for the custom view.
    CharSequence text = getText();
    if (!TextUtils.isEmpty(text)) {
        event.getText().add(text);
    }
}

@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    // Call the super implementation to let super classes
    // set appropriate event properties. Then, add the new checked
    // property that is not supported by a super class.
    event.setChecked(isChecked());
}

@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(info);
    // Call the super implementation to let super classes set
    // appropriate info properties. Then, add the checkable and checked
    // properties that are not supported by a super class.
    info.setCheckable(true);
    info.setChecked(isChecked());
    // You typically only need to add the text for the custom view.
    CharSequence text = getText();
    if (!TextUtils.isEmpty(text)) {
        info.setText(text);
    }
}

Sie können diese Methoden direkt in Ihrer benutzerdefinierten Ansichtsklasse implementieren.

Benutzerdefinierten Kontext für Bedienungshilfen bereitstellen

Bedienungshilfen können die Hierarchie der übergeordneten Ansicht einer Benutzeroberfläche prüfen das ein Bedienungshilfen-Ereignis generiert. Dadurch können Bedienungshilfen umfassendere Informationen, die Nutzenden helfen.

Es kann vorkommen, dass Bedienungshilfen keine angemessenen Informationen aus der Ansicht abrufen. Hierarchie. Ein Beispiel hierfür ist ein Steuerelement auf einer benutzerdefinierten Oberfläche, das zwei oder mehr separat anklickbare Bereiche wie ein Kalendersteuerelement. In diesem Fall können die Dienste nicht enthalten, da die anklickbaren Unterabschnitte nicht Teil der Ansichtshierarchie sind.

Abbildung 1: Eine benutzerdefinierte Kalenderansicht mit auswählbaren Tageselementen

In dem Beispiel in Abbildung 1 ist der gesamte Kalender als einzelne Ansicht implementiert, sodass die Barrierefreiheit Dienste erhalten nicht genügend Informationen über den Inhalt der Ansicht und die Auswahl des Nutzers angezeigt, es sei denn, der Entwickler stellt zusätzliche Informationen bereit. Wenn ein Nutzer beispielsweise auf Am Tag mit dem Label 17 erhält das Framework für Barrierefreiheit im Internet nur die Beschreibungsinformationen, für das gesamte Kalendersteuerelement. In diesem Fall meldet die Bedienungshilfe TalkBack „Kalender“ oder „April-Kalender“ und der Nutzer weiß nicht, welcher Tag ausgewählt wurde.

Um angemessene Kontextinformationen für Bedienungshilfen in solchen Situationen zur Verfügung zu stellen, bietet die Möglichkeit, eine virtuelle Ansichtshierarchie festzulegen. Eine virtuelle Ansichtshierarchie ist eine App-Entwicklern eine ergänzende Ansichtshierarchie zu den Bedienungshilfen zu bieten, die den Informationen auf dem Bildschirm entsprechen. So können Bedienungshilfen für die Nutzenden nützliche Kontextinformationen bieten.

Eine weitere Situation, in der eine virtuelle Ansichtshierarchie benötigt werden könnte, ist eine Benutzeroberfläche mit eine Reihe von View-Steuerelementen, die eng miteinander verbunden sind, wobei eine Aktion auf sich auf den Inhalt eines oder mehrerer Elemente auswirkt, wie z. B. bei einer Zahlenauswahl mit separaten und Abwärtstasten. In diesem Fall können die Bedienungshilfen keine angemessenen Informationen erhalten, da ein durch eine Aktion auf einem Steuerelement Inhalte in einem anderen ändert und die Beziehung dieser Kontrollen möglicherweise nicht für den Dienst deutlich sichtbar sein.

Gruppieren Sie in diesem Fall die zugehörigen Steuerelemente mit einer übergeordneten Ansicht und stellen Sie eine virtuelle Hierarchie dieses Containers anzeigen, um die Informationen und das Verhalten der Steuerelementen.

Um eine virtuelle Ansichtshierarchie für eine Ansicht bereitzustellen, überschreiben Sie die getAccessibilityNodeProvider() in Ihrer benutzerdefinierten Ansichtsgruppe hinzufügen und eine Implementierung AccessibilityNodeProvider. Sie können eine virtuelle Ansichtshierarchie implementieren, indem Sie die Support Library mit dem ViewCompat.getAccessibilityNodeProvider() und eine Implementierung mit AccessibilityNodeProviderCompat.

Erleichterung der Bereitstellung von Informationen für Bedienungshilfen und der Verwaltung auf Barrierefreiheit konzentrieren, können Sie ExploreByTouchHelper Er stellt ein AccessibilityNodeProviderCompat bereit und kann als AccessibilityDelegateCompat durch Anruf setAccessibilityDelegate Ein Beispiel finden Sie unter ExploreByTouchHelperActivity ExploreByTouchHelper wird auch von Framework-Widgets wie den CalendarView, durch die Kinderansicht SimpleMonthView

Benutzerdefinierte Touch-Ereignisse verarbeiten

Für Steuerelemente für die benutzerdefinierte Ansicht ist möglicherweise ein nicht standardmäßiges Verhalten bei Touch-Ereignissen erforderlich, wie in den folgenden Beispielen.

Klickbasierte Aktionen definieren

Wenn Ihr Widget das OnClickListener oder OnLongClickListener verarbeitet das System ACTION_CLICK und ACTION_LONG_CLICK. Aktionen für Sie. Wenn Ihre App ein benutzerdefiniertes Widget verwendet, das auf dem OnTouchListener-Oberfläche Definieren Sie benutzerdefinierte Handler für die klickbasierten Bedienungshilfen. Rufen Sie dazu die Methode replaceAccessibilityAction() , wie im folgenden Code-Snippet gezeigt:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...

    // Assumes that the widget is designed to select text when tapped, and selects
    // all text when tapped and held. In its strings.xml file, this app sets
    // "select" to "Select" and "select_all" to "Select all".
    ViewCompat.replaceAccessibilityAction(
        binding.textSelectWidget,
        ACTION_CLICK,
        getString(R.string.select)
    ) { view, commandArguments ->
        selectText()
    }

    ViewCompat.replaceAccessibilityAction(
        binding.textSelectWidget,
        ACTION_LONG_CLICK,
        getString(R.string.select_all)
    ) { view, commandArguments ->
        selectAllText()
    }
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...

    // Assumes that the widget is designed to select text when tapped, and select
    // all text when tapped and held. In its strings.xml file, this app sets
    // "select" to "Select" and "select_all" to "Select all".
    ViewCompat.replaceAccessibilityAction(
            binding.textSelectWidget,
            ACTION_CLICK,
            getString(R.string.select),
            (view, commandArguments) -> selectText());

    ViewCompat.replaceAccessibilityAction(
            binding.textSelectWidget,
            ACTION_LONG_CLICK,
            getString(R.string.select_all),
            (view, commandArguments) -> selectAllText());
}

Benutzerdefinierte Klickereignisse erstellen

Ein benutzerdefiniertes Steuerelement kann die onTouchEvent(MotionEvent) Listener-Methode zur Erkennung der ACTION_DOWN und ACTION_UP Ereignisse und ein spezielles Klickereignis auslösen. Zur Aufrechterhaltung der Kompatibilität mit Bedienungshilfen dieses benutzerdefinierte Klickereignis verarbeitet, muss Folgendes tun:

  1. Generiere ein entsprechendes AccessibilityEvent für die interpretierte Klickaktion.
  2. Aktivieren Sie Bedienungshilfen, um die benutzerdefinierte Klickaktion für Nutzer auszuführen, die diese nicht können einen Touchscreen verwenden.

Damit diese Anforderungen effizient verarbeitet werden können, muss Ihr Code den Parameter Methode performClick(), Dieser muss die Superimplementierung dieser Methode aufrufen und dann die Aktionen ausführen, die für das Klickereignis erforderlich sind. Wenn die benutzerdefinierte Klickaktion erkannt wird, muss dieser Code Ihre performClick()-Methode. Das folgende Codebeispiel veranschaulicht dieses Muster.

Kotlin

class CustomTouchView(context: Context) : View(context) {

    var downTouch = false

    override fun onTouchEvent(event: MotionEvent): Boolean {
        super.onTouchEvent(event)

        // Listening for the down and up touch events.
        return when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                downTouch = true
                true
            }

            MotionEvent.ACTION_UP -> if (downTouch) {
                downTouch = false
                performClick() // Call this method to handle the response and
                // enable accessibility services to
                // perform this action for a user who can't
                // tap the touchscreen.
                true
            } else {
                false
            }

            else -> false  // Return false for other touch events.
        }
    }

    override fun performClick(): Boolean {
        // Calls the super implementation, which generates an AccessibilityEvent
        // and calls the onClick() listener on the view, if any.
        super.performClick()

        // Handle the action for the custom click here.

        return true
    }
}

Java

class CustomTouchView extends View {

    public CustomTouchView(Context context) {
        super(context);
    }

    boolean downTouch = false;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        // Listening for the down and up touch events
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downTouch = true;
                return true;

            case MotionEvent.ACTION_UP:
                if (downTouch) {
                    downTouch = false;
                    performClick(); // Call this method to handle the response and
                                    // enable accessibility services to
                                    // perform this action for a user who can't
                                    // tap the touchscreen.
                    return true;
                }
        }
        return false; // Return false for other touch events.
    }

    @Override
    public boolean performClick() {
        // Calls the super implementation, which generates an AccessibilityEvent
        // and calls the onClick() listener on the view, if any.
        super.performClick();

        // Handle the action for the custom click here.

        return true;
    }
}

Mit dem vorherigen Muster wird sichergestellt, dass das benutzerdefinierte Klickereignis mit Bedienungshilfen kompatibel ist. mithilfe der Methode performClick() ein Bedienungshilfen-Ereignis generieren und einen Einstiegspunkt bereitstellen, über den Bedienungshilfen im Namen eines Nutzers handeln können, der die benutzerdefinierte Click-Event.

<ph type="x-smartling-placeholder">