Barrierefreies Kotlin: Code, der niemanden ausschließt

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Warum Accessibility in Kotlin eine Superkraft ist – und kein lästiges Ankreuzfeld

\n\n

Stell dir vor: Du hast eine coole App in Kotlin geschrieben. Schönes Material Design, flüssige Animationen, reaktive Streams. Du bist stolz auf deinen Code. Aber dann stellt sich heraus, dass eine Person mit Sehschwäche den „Kaufen“-Button nicht drücken kann, weil TalkBack ihn als „nicht beschrifteter Button“ vorliest. Oder ein Nutzer mit Zittern in den Händen verfehlt den winzigen Schalter.

\n\n

Accessibility (Barrierefreiheit) ist keine langweilige Bürokratie. Es geht darum, dass dein Kotlin-Code für jeden funktioniert. Laut WHO haben über eine Milliarde Menschen eine Behinderung. Sie zu ignorieren bedeutet, Zielgruppe zu verlieren – und ehrlich gesagt, ein schlechter Entwickler zu sein.

\n\n

In diesem Artikel zeigen wir dir, wie du barrierefreien Kotlin-Code schreibst – ohne Schmerz. Ohne Tonnen von Boilerplate-Code. Mit lebendigen Beispielen, die du direkt kopieren und einfügen kannst.

\n\n

Grundprinzipien: ContentDescription – dein bester Freund

\n\n

Der häufigste Fehler bei Accessibility ist das Fehlen von Beschreibungen für UI-Elemente. Das System TalkBack (Screenreader auf Android) kann Bilder oder Icons nicht lesen. Es braucht Text.

\n\n

In Kotlin erledigst du das mit dem Attribut contentDescription. Aber nicht einfach „Button“, sondern sinnvoll.

\n\n

Schlechtes Beispiel (mach das nicht)

\n
imageView.contentDescription = "Button"
\n\n

Gutes Beispiel

\n
binding.fabAddTask.contentDescription = "Neue Aufgabe hinzufügen"
\n\n

Wenn ein Icon dekorativ ist (nur zur Verschönerung) – setze contentDescription = null, damit TalkBack es ignoriert.

\n\n
// Dekoratives Icon – Nutzer nicht ablenken\nbinding.decorativeIcon.contentDescription = null
\n\n

Tipp: Nutze String-Ressourcen (strings.xml), um Lokalisierung zu unterstützen. Hardcode keinen deutschen Text in Kotlin-Dateien.

\n\n

Semantische Auszeichnung: Dem System sagen, was wichtig ist

\n\n

Standard-Views (Button, TextView) machen ihre Sache gut, aber benutzerdefinierte Komponenten brechen oft die Accessibility. In Kotlin können wir die Semantik explizit festlegen.

\n\n

Einem Element eine Rolle geben

\n
binding.customView.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES\nbinding.customView.accessibilityDelegate = object : View.AccessibilityDelegate() {\n    override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {\n        super.onInitializeAccessibilityNodeInfo(host, info)\n        info.text = "Aktueller Wert: ${viewModel.value}"\n        info.contentDescription = "Lautstärkeregler"\n    }\n}
\n\n

Dieser Code sagt dem System: „Hey, das ist kein einfaches Quadrat, das ist ein Schieberegler!“. TalkBack versteht, dass das Element interaktiv ist, und kann korrekt damit interagieren.

\n\n

Elemente gruppieren

\n

Wenn du eine Produktkarte mit Bild, Preis und Name hast – fasse sie in einem Fokus zusammen. Sonst muss der Nutzer drei einzelne Elemente nacheinander anhören.

\n\n
binding.cardProduct.apply {\n    isFocusable = true\n    contentDescription = "Produkt: ${product.name}, Preis: ${product.price} Euro"\n}
\n\n

Jetzt liest TalkBack alle Informationen auf einmal vor.

\n\n

Aktionsnavigation: Tastatur und D-Pad

\n\n

Nicht alle Nutzer tippen auf den Bildschirm. Manche verwenden eine Tastatur (per OTG) oder einen D-Pad (Fernbedienung). Deine App muss auch ohne Berührung bedienbar sein.

\n\n

In Kotlin löst du das mit focusable und der Fokus-Reihenfolge (nextFocusDown, nextFocusForward).

\n\n
binding.buttonNext.nextFocusForwardId = R.id.buttonConfirm\nbinding.buttonConfirm.nextFocusDownId = R.id.buttonCancel
\n\n

Prüfe, ob alle interaktiven Elemente den Fokus erhalten. Ein häufiger Fehler ist ein TextView mit ClickableSpan (Link im Text). Standardmäßig wird er nicht fokussiert. So behebst du das:

\n\n
binding.textWithLink.movementMethod = LinkMovement

Blogs

Buchempfehlungen