Přístupný přepínač (Switch) v Android View
Popisek a přepínač vedle sebe jako dva samostatné prvky rozkladu (TextView + Switch) jsou pro TalkBack dvě oddělené zastávky — na přepínač se dostanete zvlášť a uslyšíte jen „přepínač, zapnuto" bez informace, co vlastně přepíná.
1. Špatně — text a přepínač jako dva samostatné View
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="Zvuk při dosažení poslední položky" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchSound"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
2. Správně — text přímo na přepínači
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchSound"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Zvuk při dosažení poslední položky" />
MaterialSwitch (aktuálně doporučená náhrada za starší SwitchMaterial i za čistý Switch/SwitchCompat) je potomek CompoundButton, který svůj android:text vystavuje jako součást přístupného jména automaticky, spolu se stavem. TalkBack přečte „Zvuk při dosažení poslední položky, přepínač, zapnuto" jedním krokem — bez jakékoli ruční práce navíc.
3. Když opravdu potřebujete text a přepínač jako oddělené View
Vestavěný text nejde použít, pokud layout vyžaduje text u levého okraje a přepínač u pravého, roztažené na celou šířku řádku. Nejbližší náhrada je udělat z celého řádku jeden fokusovatelný celek:
<LinearLayout
android:id="@+id/switchRow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:focusable="false"
android:text="Zvuk při dosažení poslední položky" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/switchSound"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false" />
</LinearLayout>
clickable="false"/focusable="false" na obou vnitřních prvcích a clickable="true"/focusable="true" na obalujícím LinearLayout sloučí text potomků do jedné TalkBack zastávky. Tady je ale mezera, kterou se mi nepodařilo dohledat oficiálně zdokumentovanou: sloučení textu je popsané, ale nikde jsem nenašel potvrzení, že se stejně automaticky přenese i stav (zapnuto/vypnuto) a role „přepínač" ze Switch, který teď sám nedostává fokus. V praxi to pravděpodobně vyžaduje doplnit na řádek AccessibilityDelegate, který stav a roli předá ručně:
ViewCompat.setAccessibilityDelegate(switchRow, object : AccessibilityDelegateCompat() {
override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) {
super.onInitializeAccessibilityNodeInfo(host, info)
info.className = android.widget.Switch::class.java.name
info.isCheckable = true
info.isChecked = switchSound.isChecked
}
})
Tuhle variantu si před nasazením ověřte přímo se zapnutým TalkBackem — na rozdíl od zbytku článku tahle část nemá oporu v žádném oficiálním dokumentu, který bych dohledal.
Proč to takhle je
Switch/MaterialSwitchjeCompoundButtona nativně vystavuje svůjandroid:textjako součást přístupného jména společně se stavem — proto první, jednodušší řešení nepotřebuje nic navíc.- Sloučení přes
clickable/focusableje oficiálně zdokumentované pro text potomků, ne prokazatelně pro stav a roli — to je rozdíl oproti přístupům, kde jeden modifier/atribut řeší obojí najednou. MaterialSwitchje aktuálně doporučená volba — lint upozorňuje na použití staršího čistéhoSwitchv XML.
Pravidla
- WCAG 4.1.2 (Název, role, hodnota) — přepínač musí programově hlásit svou roli, stav i název jako jeden celek, ne jako tři nesouvisející kusy informace.
Komentáře
Zatím zde nejsou žádné komentáře. Buďte první, kdo napíše svůj názor.
Přidat komentář k „Přístupný přepínač (Switch) v Android View“