Material、Compose UI 和 Foundation API 會在預設情況下實作並提供許多無障礙做法。這些元素包含內建語意,可根據其特定角色和功能提供服務,也就是說,只要稍微調整或不調整,即可提供大部分的無障礙支援。
使用適當的 API 來滿足適當的用途,通常表示元件會提供預先定義的無障礙行為,涵蓋標準使用情境,但請務必再次確認這些預設值是否符合您的無障礙需求。如果不是,Compose 也提供其他方式,可滿足更具體的需求。
瞭解 Compose API 中的預設無障礙語義和模式,有助於您瞭解如何在設計時考量無障礙功能,以及如何在更多自訂元件中支援無障礙功能。
觸控目標大小下限
任何使用者可點擊、輕觸或互動的螢幕元素,都必須設為適當大小,方便使用者進行互動。設定這些元素的大小時,請務必將大小下限設為 48dp,以便正確遵循「Material Design 無障礙指南」。
Material 元件,例如 Checkbox
、RadioButton
、Switch
、Slider
和 Surface
:請在內部設定此大小下限,但僅限元件可以接收使用者動作時。舉例來說,如果 Checkbox
的 onCheckedChange
參數設為非空值,系統就會在其中包含至少 48 dp 的寬度和高度。
@Composable private fun CheckableCheckbox() { Checkbox(checked = true, onCheckedChange = {}) }

當 onCheckedChange
參數設為空值時,系統不會納入邊框間距,因為該元件無法直接互動。
@Composable private fun NonClickableCheckbox() { Checkbox(checked = true, onCheckedChange = null) }

導入 Switch
、RadioButton
或 Checkbox
等選取控制項時,您通常會將可點擊的行為推送至父項容器,並將可組合項的點擊回呼設為 null
,然後在可組合父項中新增 toggleable
或 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) } } }

如果可點擊的可組合項大小小於最低觸控目標大小,Compose 仍會增加觸控目標大小。方法是將觸控目標大小擴大到可組合項的範圍之外。
以下範例包含一個非常小的可點擊項 Box
。觸控目標區域會自動擴大到 Box
的範圍以外,因此輕觸 Box
旁邊的按鈕仍會觸發點擊事件。
@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) ) } }

為避免不同可組合項的觸控區域重疊,請一律為可組合項使用足夠大的最小尺寸。在範例中,則意味著使用 sizeIn
修飾符來設定內部方塊的最小大小:
@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) ) } }

圖形元素
在您定義 Image
或 Icon
可組合項時,Android 架構無法自動瞭解應用程式正在顯示的內容。您必須傳送圖形元素的文字說明。
請設想一個螢幕,可供使用者與好友分享目前的頁面。這個畫面包含可點擊的共用圖示:

單憑藉圖示,Android 架構無從向視障使用者說明。Android 架構需要圖示的其他文字說明。
contentDescription
參數會描述圖形元素。請使用本地化字串,因為使用者會看到這個字串。
@Composable private fun ShareButton(onClick: () -> Unit) { IconButton(onClick = onClick) { Icon( imageVector = Icons.Filled.Share, contentDescription = stringResource(R.string.label_share) ) } }
有些圖形元素只是單純裝飾用途,而您可能不想向使用者傳達這些元素。將 contentDescription
參數設為 null
時,您必須向 Android 架構表明這個元素沒有相關聯的動作或狀態。
@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
主要用於圖形元素,例如圖片。Button
或 Text
等 Material 元件,以及 clickable
或 toggleable
等可執行行為,都會附帶其他預先定義的語意,用於說明其內在行為,並可透過其他 Compose API 進行變更。
互動式元素
Material 和 Foundation Compose API 會透過 clickable
和 toggleable
修飾符 API,製作使用者可互動的 UI 元素。由於可互動的元件可能包含多個元素,因此 clickable
和 toggleable
會預設合併子項的語意,以便將元件視為單一邏輯實體。
舉例來說,Material Button
可能包含子項圖示和部分文字。Material Button 預設會合併子項語意,而非將子項視為個別項目,以便無障礙服務依據這些項目進行分組:

同樣地,使用 clickable
修飾符也會導致可組合函式將子項的語意合併為單一實體,並透過對應的動作表示法傳送至無障礙服務:
Row( // Uses `mergeDescendants = true` under the hood modifier = Modifier.clickable { openArticle() } ) { Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Open", ) Text("Accessibility in Compose") }
您也可以在可點選的父項上設定特定 onClickLabel
,為無障礙服務提供額外資訊,並提供更精緻的動作表示方式:
Row( modifier = Modifier .clickable(onClickLabel = "Open this article") { openArticle() } ) { Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Open" ) Text("Accessibility in Compose") }
以 TalkBack 為例,這個 clickable
輔助鍵及其點擊標籤可讓 TalkBack 提供「輕觸兩下即可開啟此文章」的動作提示,而非更通用的「輕觸兩下即可啟用」的預設回饋。
這項意見回饋會因動作類型而異。長按會提供 TalkBack 提示「輕觸兩下並長按」,接著會顯示標籤:
Row( modifier = Modifier .combinedClickable( onLongClickLabel = "Bookmark this article", onLongClick = { addToBookmarks() }, onClickLabel = "Open this article", onClick = { openArticle() }, ) ) {}
在某些情況下,您可能無法直接存取 clickable
修飾符 (例如,當它設在較低的巢狀層級時),但仍想將通知標籤從預設值變更。為此,請使用 semantics
修飾符,在其中設定點擊標籤,以便修改動作表示法,並將 clickable
設定與修改公告分開:
@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 } ) } ) }
在這種情況下,您不需要兩次傳遞點擊動作,因為 clickable
或 Button
等現有的 Compose API 會為您處理這項操作。這是因為合併邏輯可確保系統會針對現有資訊採取最外層的修飾符標籤和動作。
在前述範例中,openArticle()
點擊動作會由 NestedArticleListItem
自動傳遞至其 clickable
語意,並可在第二個語意修飾符動作中保留空值。不過,點擊標籤是從第二個語意修飾符 onClick(label = "Open this article")
取得,因為第一個語意修飾符中並未出現該標籤。
您可能會遇到以下情況:您預期子語義會合併至父語義,但實際上並未發生。詳情請參閱「合併和清除」一節。
自訂元件
就自訂元件而言,原則上,您應在「材質」程式庫或其他 Compose 程式庫中查看類似元件的實作方式,並模仿或修改其無障礙行為 (如果可行)。
舉例來說,如果您要將「材質」Checkbox
替換成自己的實作項目,查看現有的核取方塊實作項目,系統會提醒您新增 triStateToggleable
修飾符,以便處理此元件的無障礙屬性。
此外,請多多利用基礎修飾符,因為前者內建便有考慮無障礙功能,以及本節所述的現有 Compose 做法。
您也可以在「清除並設定語意」一節中找到自訂切換按鈕元件的範例,以及如何在API 規範中支援自訂元件的無障礙功能的詳細資訊。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- Compose 中的無障礙功能
- [Compose 中的 Material Design 2][19]
- 測試 Compose 版面配置