Interfejsy API Material, Compose UI i Foundation implementują i oferują domyślnie wiele praktyk ułatwień dostępu. Zawierają one wbudowaną semantykę, która odpowiada ich roli i funkcji, co oznacza, że większość ułatwień jest zapewniana bez konieczności dodatkowej pracy.
Korzystanie z odpowiednich interfejsów API do odpowiednich celów zwykle oznacza, że komponenty mają wstępnie zdefiniowane zachowania ułatwień dostępu, które obejmują standardowe przypadki użycia. Pamiętaj jednak, aby sprawdzić, czy te domyślne ustawienia odpowiadają Twoim potrzebom w zakresie ułatwień dostępu. Jeśli nie, Compose oferuje też sposoby na spełnienie bardziej szczegółowych wymagań.
Znajomość domyślnej semantyki ułatwia zrozumienie, jak używać interfejsów API Compose z uwzględnieniem ułatwień dostępu, a także jak obsługiwać ułatwienia dostępu w większej liczbie komponentów niestandardowych.
Minimalne rozmiary docelowych obszarów kliknięcia
Każdy element na ekranie, który można kliknąć, dotknąć lub w inny sposób aktywować, powinien być na tyle duży, by umożliwiać skuteczną interakcję. Podczas określania rozmiaru tych elementów ustaw minimalny rozmiar na 48 dp, aby zachować zgodność z wytycznymi dotyczącymi ułatwień dostępu w interfejsie Material Design.
Składniki Material Design, takie jak Checkbox
, RadioButton
, Switch
, Slider
i Surface
, ustawiają tę minimalną wielkość wewnętrznie, ale tylko wtedy, gdy komponent może odbierać działania użytkownika. Na przykład, gdy element Checkbox
ma parametr onCheckedChange
ustawiony na wartość inną niż null, pole wyboru zawiera wypełnienie, aby jego szerokość i wysokość wynosiły co najmniej 48 dp.
@Composable private fun CheckableCheckbox() { Checkbox(checked = true, onCheckedChange = {}) }

Jeśli parametr onCheckedChange
ma wartość null, wypełnienie nie jest uwzględniane, ponieważ nie można bezpośrednio wchodzić w interakcję z elementem.
@Composable private fun NonClickableCheckbox() { Checkbox(checked = true, onCheckedChange = null) }

Podczas implementowania elementów sterujących wyborem, takich jak Switch
, RadioButton
lub Checkbox
, przenosisz zazwyczaj możliwość kliknięcia do nadrzędnego kontenera, ustawiając w funkcji kompozytowanej wartość null
i dodając do niej modyfikator toggleable
lub selectable
.
@Composable private fun CheckableRow() { MaterialTheme { var checked by remember { mutableStateOf(false) } Row( Modifier .toggleable( value = checked, role = Role.Checkbox, onValueChange = { checked = !checked } ) .padding(16.dp) .fillMaxWidth() ) { Text("Option", Modifier.weight(1f)) Checkbox(checked = checked, onCheckedChange = null) } } }

Jeśli rozmiar kompozytywny, który można kliknąć, jest mniejszy niż minimalny rozmiar docelowego elementu dotykowego, funkcja Compose zwiększa rozmiar docelowego elementu dotykowego. Dzieje się tak, gdy rozmiar docelowy dotykowy wykracza poza granice kompozytu.
Ten przykład zawiera bardzo mały przycisk Box
, który można kliknąć. Obszar dotykowy jest automatycznie rozszerzany poza granice elementu Box
, więc kliknięcie obok elementu Box
nadal powoduje wywołanie zdarzenia kliknięcia.
@Composable private fun SmallBox() { var clicked by remember { mutableStateOf(false) } Box( Modifier .size(100.dp) .background(if (clicked) Color.DarkGray else Color.LightGray) ) { Box( Modifier .align(Alignment.Center) .clickable { clicked = !clicked } .background(Color.Black) .size(1.dp) ) } }

Aby zapobiec nakładaniu się obszarów dotykowych różnych komponentów, zawsze używaj wystarczająco dużego minimalnego rozmiaru komponentu. W tym przykładzie oznacza to użycie modyfikatora sizeIn
, aby ustawić minimalny rozmiar wewnętrznego pola:
@Composable private fun LargeBox() { var clicked by remember { mutableStateOf(false) } Box( Modifier .size(100.dp) .background(if (clicked) Color.DarkGray else Color.LightGray) ) { Box( Modifier .align(Alignment.Center) .clickable { clicked = !clicked } .background(Color.Black) .sizeIn(minWidth = 48.dp, minHeight = 48.dp) ) } }

Elementy graficzne
Gdy definiujesz komponent Image
lub Icon
, platforma Android nie ma automatycznego sposobu na zrozumienie, co aplikacja wyświetla. Musisz podać tekstowy opis elementu graficznego.
Wyobraź sobie ekran, na którym użytkownik może udostępnić bieżącą stronę znajomym. Ten ekran zawiera ikonę udostępniania, którą można kliknąć:

Na podstawie samej ikony framework Androida nie może opisać jej użytkownikowi niedowidzącego. Platforma Android wymaga dodatkowego opisu ikony.
Parametr contentDescription
opisuje element graficzny. Użyj zlokalizowanego ciągu znaków, ponieważ jest on widoczny dla użytkownika.
@Composable private fun ShareButton(onClick: () -> Unit) { IconButton(onClick = onClick) { Icon( imageVector = Icons.Filled.Share, contentDescription = stringResource(R.string.label_share) ) } }
Niektóre elementy graficzne mają charakter czysto dekoracyjny i możesz nie chcieć przekazywać ich użytkownikowi. Gdy ustawisz parametr contentDescription
na null
, poinformujesz platformę Android, że ten element nie ma powiązanych działań ani stanu.
@Composable private fun PostImage(post: Post, modifier: Modifier = Modifier) { val image = post.imageThumb ?: painterResource(R.drawable.placeholder_1_1) Image( painter = image, // Specify that this image has no semantic meaning contentDescription = null, modifier = modifier .size(40.dp, 40.dp) .clip(MaterialTheme.shapes.small) ) }
contentDescription
jest przeznaczony głównie do elementów graficznych, takich jak obrazy. Składniki materiału, takie jak Button
lub Text
, oraz interaktywne zachowania, takie jak clickable
lub toggleable
, są dostarczane z innymi zdefiniowanymi semantycznie elementami, które opisują ich zachowanie. Można je zmieniać za pomocą innych interfejsów API Compose.
Elementy interaktywne
Interfejsy API Material i Foundation Compose umożliwiają tworzenie elementów interfejsu użytkownika, z którymi użytkownicy mogą wchodzić w interakcje za pomocą interfejsów modyfikatora clickable
i toggleable
. Ponieważ komponenty interaktywne mogą składać się z wielu elementów, komponenty clickable
i toggleable
domyślnie scalają semantykę swoich elementów podrzędnych, dzięki czemu komponent jest traktowany jako jedna jednostka logiczna.
Na przykład element Materiał Button
może składać się z ikony podrzędnej i tekstu.
Zamiast traktować elementy podrzędne jako osobne elementy, przycisk Material Button domyślnie scala ich semantykę, aby usługi ułatwień dostępu mogły je odpowiednio grupować:

Podobnie modyfikator clickable
powoduje, że kompozybilny element scala semantykę swoich potomków w jeden element, który jest wysyłany do usług ułatwień dostępu z odpowiednią reprezentacją działania:
Row( // Uses `mergeDescendants = true` under the hood modifier = Modifier.clickable { openArticle() } ) { Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Open", ) Text("Accessibility in Compose") }
Możesz też ustawić konkretny element onClickLabel
w przypadku elementów klikalnych nadrzędnych, aby przekazać dodatkowe informacje usługom ułatwień dostępu i zapewnić bardziej dopracowane przedstawienie działania:
Row( modifier = Modifier .clickable(onClickLabel = "Open this article") { openArticle() } ) { Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Open" ) Text("Accessibility in Compose") }
W przypadku TalkBacka ten modyfikator clickable
i jego etykieta kliknięcia umożliwiłyby TalkBackowi wyświetlanie wskazówki „Kliknij dwukrotnie, aby otworzyć ten artykuł”, zamiast ogólnego domyślnego komunikatu „Kliknij dwukrotnie, aby aktywować”.
Te informacje różnią się w zależności od typu działania. Długie kliknięcie wyświetli podpowiedź TalkBack „Dwa razy dotknij i przytrzymaj, aby” oraz etykietę:
Row( modifier = Modifier .combinedClickable( onLongClickLabel = "Bookmark this article", onLongClick = { addToBookmarks() }, onClickLabel = "Open this article", onClick = { openArticle() }, ) ) {}
W niektórych przypadkach możesz nie mieć bezpośredniego dostępu do modyfikatora clickable
(na przykład gdy jest on ustawiony gdzieś w niższej warstwie), ale mimo to chcesz zmienić etykietę komunikatu z domyślnej. Aby to zrobić, oddziel ustawienie
clickable
od modyfikacji ogłoszenia za pomocą modyfikatora semantics
i ustawienia etykiety kliknięcia, aby zmodyfikować reprezentację działania:
@Composable private fun ArticleList(openArticle: () -> Unit) { NestedArticleListItem( // Clickable is set separately, in a nested layer: onClickAction = openArticle, // Semantics are set here: modifier = Modifier.semantics { onClick( label = "Open this article", action = { // Not needed here: openArticle() true } ) } ) }
W tym przypadku nie musisz przekazywać akcji kliknięcia dwukrotnie, ponieważ istniejące interfejsy Compose API, takie jak clickable
czy Button
, robią to za Ciebie. Dzieje się tak, ponieważ logika scalania zapewnia, że dla obecnych informacji są podejmowane działania dotyczące zewnętrznej etykiety modyfikatora i działania.
W poprzednim przykładzie działanie kliknięcia openArticle()
jest przekazywane przez NestedArticleListItem
automatycznie do semantyki clickable
i może być puste w drugim działaniu modyfikatora semantyki. Etykieta kliknięcia jest jednak pobierana z drugiego modyfikatora semantycznego (onClick(label = "Open this article")
), ponieważ nie była obecna w pierwszym.
Możesz napotkać sytuacje, w których oczekujesz, że semantyka podrzędna zostanie scalona z elementem nadrzędnym, ale tak się nie dzieje. Więcej informacji znajdziesz w sekcji Łączenie i czyszczenie.
Komponenty niestandardowe
W przypadku komponentów niestandardowych warto przyjrzeć się implementacji podobnego komponentu w bibliotece Material lub innych bibliotekach Compose i naśladować lub modyfikować jego zachowanie w zakresie ułatwień dostępu, gdy jest to uzasadnione.
Jeśli na przykład zamierzasz zastąpić komponent Checkbox
własną implementacją, sprawdzenie istniejącej implementacji pola wyboru przypomni Ci, aby dodać modyfikator triStateToggleable
, który obsługuje właściwości ułatwień dostępu tego komponentu.
Dodatkowo warto często używać modyfikatorów Foundation, ponieważ uwzględniają one standardowe kwestie dotyczące dostępności, a także istniejące praktyki dotyczące Compose opisane w tej sekcji.
Przykład niestandardowego komponentu przełącznika znajdziesz w sekcji Wyraźne i ukryte semantyka, a więcej szczegółowych informacji o wsparciu dostępności w komponentach niestandardowych znajdziesz w wytycznych dotyczących interfejsu API.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy obsługa JavaScript jest wyłączona
- Ułatwienia dostępu w sekcji „Tworzenie wiadomości”
- [Material Design 2 w Compose][19]
- Testowanie układu okna tworzenia wiadomości