Material、Compose UI 和 Foundation API 預設會實作並提供許多無障礙功能設計做法。這些元素內含遵循特定角色和功能的內建語意。這表示大部分的無障礙支援功能都已提供,幾乎不需要額外作業。
為適當用途使用適當的 API,表示元件通常會提供預先定義的無障礙行為,涵蓋標準用途。不過,請務必再次確認這些預設值是否符合您的無障礙需求。如果沒有,Compose 也提供方法,可滿足更具體的需求。
瞭解 Compose API 中的預設無障礙語意和模式,有助於您使用這些 API 時兼顧無障礙功能。還能協助您在更多自訂元件中支援無障礙功能。
觸控目標大小下限
任何使用者可點擊、輕觸或進行互動的螢幕元素,都必須設為適當大小,方便使用者進行互動。設定這些元素的大小時,請務必將大小下限設為 48dp,以便正確遵循「Material Design 無障礙功能指南」。
「材質」元件,例如 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) 和可執行的行為 (例如 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 } ) } ) }
您不需要傳遞兩次點擊動作。現有的 Compose API (例如 clickable 或 Button) 會為您處理這項作業。合併邏輯會驗證最外層的修飾符標籤和動作是否適用於現有資訊。在上述範例中,NestedArticleListItem 會自動將 openArticle() 點選動作傳遞至其 clickable 語意。您可以在第二個語意修飾詞動作中,將點擊動作留空。不過,由於第一個語意修飾符中沒有點擊標籤,因此系統會從第二個語意修飾符 onClick(label = "Open this document") 中擷取。
您可能會遇到預期子項語意會合併到父項語意中,但實際並未發生的情況。如需更多資訊,請參閱「合併及清除」一文。
自訂元件
建構自訂元件時,請查看 Material 程式庫或其他 Compose 程式庫中類似元件的實作項目。然後視需要模擬或修改其無障礙功能行為。舉例來說,如果您將 Material Checkbox 替換成自己的實作項目,查看現有的 Checkbox 實作項目時,會提醒您加入 triStateToggleable 修飾符,負責處理元件的無障礙屬性。此外,請多多利用 Foundation 修飾符,因為前者內建便有考慮無障礙功能,且包含本節涵蓋的現有 Compose 做法。
您也可以在「清除及設定語意區段」中找到自訂切換按鈕元件的範例,並在 API 指南中找到如何支援自訂元件無障礙功能的詳細資訊。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- Compose 中的無障礙功能
- 測試 Compose 版面配置
