如要協助有無障礙需求的使用者順利使用您的應用程式,請設計應用程式的 可支援重要的無障礙需求
考量最低觸控目標大小
任何使用者可點擊、輕觸或互動的螢幕元素,都必須設為 大小足以產生可靠的互動設定這些元素大小時,請務必 將最小尺寸設為 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) ) } }
新增點擊標籤
您可以使用點擊標籤,針對使用者的互動行為加上語意含義 可組合函式。點擊標籤可說明使用者與 可組合函式。無障礙服務會根據點擊標籤,說明應用程式 或有特定需求的使用者
在 clickable
修飾符中傳遞參數,設定點擊標籤:
@Composable private fun ArticleListItem(openArticle: () -> Unit) { Row( Modifier.clickable( // R.string.action_read_article = "read article" onClickLabel = stringResource(R.string.action_read_article), onClick = openArticle ) ) { // .. } }
此外,如果沒有可點擊修飾符的存取權,請將 語意修飾符中的點擊標籤:
@Composable private fun LowLevelClickLabel(openArticle: () -> Boolean) { // R.string.action_read_article = "read article" val readArticleLabel = stringResource(R.string.action_read_article) Canvas( Modifier.semantics { onClick(label = readArticleLabel, action = openArticle) } ) { // .. } }
描述視覺元素
定義 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
。問問自己,該元素是否傳達出
使用者需執行任務如果沒有,則最好將
說明
合併元素
無障礙服務 (例如 TalkBack 和切換控制功能) 可讓使用者在不同元素間移動畫面聚焦。元素只聚焦於適當的精細度很重要。當畫面中的每個低層級可組合函式出現時 使用者必須與多次互動才能在畫面上移動。 如果元素過度合併,使用者可能就不知道 個元素屬於同一群組
將 clickable
修飾符套用至可組合函式時,Compose 會
會自動合併可組合項中包含的所有元素。這項機制也適用於
ListItem
;清單項目內的元素會合併在一起,而無障礙功能
這些容器視為一個元素
可以有一組可組合函式形成邏輯群組,但 群組不可點擊,或不屬於清單項目的一部分。你仍需要無障礙服務 即可將這些元素視為單一元素例如,假設某個可組合元件 會顯示使用者的顯示圖片、名稱以及一些額外資訊:
您可以使用 mergeDescendants
,讓 Compose 合併這些元素
semantics
修飾符中的參數值。如此一來,無障礙服務
請只選取合併的元素,以及子系的所有語意屬性
已合併。
@Composable private fun PostMetadata(metadata: Metadata) { // Merge elements below for accessibility purposes Row(modifier = Modifier.semantics(mergeDescendants = true) {}) { Image( imageVector = Icons.Filled.AccountCircle, contentDescription = null // decorative ) Column { Text(metadata.author.name) Text("${metadata.date} • ${metadata.readTimeMinutes} min read") } } }
無障礙服務現在一次聚焦於整個容器,合併 他們的內容:
新增自訂動作
請查看下列清單項目:
使用 TalkBack 等螢幕閱讀器聽取內容 會先選取整個項目,再選取書籤圖示。
在冗長的清單,重複性可能變得很高。更好的方法是
定義可讓使用者將商品加入書籤的自訂動作。注意事項
您也必須明確移除書籤圖示
以確定無障礙服務並未選取該類別。這個
方法是使用 clearAndSetSemantics
修飾符:
@Composable private fun PostCardSimple( /* ... */ isFavorite: Boolean, onToggleFavorite: () -> Boolean ) { val actionLabel = stringResource( if (isFavorite) R.string.unfavorite else R.string.favorite ) Row( modifier = Modifier .clickable(onClick = { /* ... */ }) .semantics { // Set any explicit semantic properties customActions = listOf( CustomAccessibilityAction(actionLabel, onToggleFavorite) ) } ) { /* ... */ BookmarkButton( isBookmarked = isFavorite, onClick = onToggleFavorite, // Clear any semantics properties set on this node modifier = Modifier.clearAndSetSemantics { } ) } }
說明元素的狀態
可組合項可定義語意的 stateDescription
,
Android 架構用來讀出可組合函式所處的狀態。適用對象
舉例來說,可切換的可組合函式可能會出現在「已勾選」狀態或「未勾選」
時間。在某些情況下,您可能會想覆寫預設的狀態說明
Compose 會使用的標籤。方法是明確指定
將可組合項定義為可切換之前,說明標籤:
@Composable private fun TopicItem(itemTitle: String, selected: Boolean, onToggle: () -> Unit) { val stateSubscribed = stringResource(R.string.subscribed) val stateNotSubscribed = stringResource(R.string.not_subscribed) Row( modifier = Modifier .semantics { // Set any explicit semantic properties stateDescription = if (selected) stateSubscribed else stateNotSubscribed } .toggleable( value = selected, onValueChange = { onToggle() } ) ) { /* ... */ } }
定義標題
應用程式有時會在同一個可捲動的容器中顯示大量內容。 舉例來說,畫面可能會顯示使用者文章的完整內容 正在閱讀:
無障礙功能的使用者無法順利瀏覽這類畫面。援助 以及哪些元素是標題在上述範例中, 子章節標題可以定義為無障礙標題。只有部分通知 例如 TalkBack 等無障礙服務 標題。
在 Compose 中,您可以透過定義可組合項目定義可組合項為「標題」
semantics
屬性:
@Composable private fun Subsection(text: String) { Text( text = text, style = MaterialTheme.typography.headlineSmall, modifier = Modifier.semantics { heading() } ) }
處理自訂可組合函式
每次將應用程式中的特定 Material 元件替換為自訂元件 就必須留意無障礙設計
假設您要將 Material Checkbox
替換為自己的實作項目。
您可能會忘記新增會控制代碼的 triStateToggleable
修飾符
此元件的無障礙功能屬性
原則上,我們來看看元件的實作 來模擬 Material 程式庫中可找到的任何無障礙功能行為。 此外,請大量使用基礎修飾符,而非 UI 層級 修飾符,因為這包括內建無障礙功能的考量重點。
利用多個 驗證其行為。
其他資源
- 無障礙功能:基礎概念和 所有 Android 應用程式開發通用的技巧
- 打造無障礙應用程式:重要步驟 讓你的應用程式更容易使用
- 提升應用程式品質的原則 無障礙功能:確保 提升應用程式的無障礙程度
- 無障礙設定測試: Android 無障礙功能的測試原則和工具