當無障礙服務瀏覽畫面上的元素時,請務必以適當的精細度將這些元素分組、分隔,甚至隱藏。如果畫面上的每個低階可組合項各自醒目顯示,使用者就必須互動許多次才能在畫面上移動。如果元素過度合併,使用者可能無法理解哪些元素在邏輯上屬於同一群組。如果畫面上有純裝飾性的元素,這些元素可能會隱藏在無障礙服務中。在這種情況下,您可以使用 Compose API 合併、清除和隱藏語義。
合併語意
將 clickable
修飾符套用至父項可組合項時,Compose 會自動合併其下的所有子項元素。如要瞭解互動式 Compose Material 和 Foundation 元件如何根據預設使用合併策略,請參閱「互動式元素」一節。
元件通常由多個可組合項組成。這些可組合項可能會形成邏輯群組,且每個可組合項都可能包含重要資訊,但您仍可能希望無障礙服務將其視為單一元素。
舉例來說,假設可組合項會顯示使用者的顯示圖片、使用者名稱和一些額外資訊:

您可以在語意輔助鍵中使用 mergeDescendants
參數,讓 Compose 合併這些元素。這樣一來,無障礙服務會將元件視為一個實體,並合併子系的所有語意屬性:
@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") } } }
無障礙服務現在一次聚焦於整個容器,並合併其內容:

每個語義屬性都有已定義的合併策略。舉例來說,ContentDescription
屬性會將所有子系 ContentDescription
值新增至清單。如要檢查語義屬性的合併策略,請前往 SemanticsProperties.kt 查看其 mergePolicy
實作項目。屬性可採用父項或子項值、將值合併至清單或字串、完全不允許合併且擲回例外狀況,或任何其他自訂合併策略。
在其他情況下,您可能會希望子語義合併至父語義,但實際上並未發生。在以下範例中,我們有含有子項元素的 clickable
清單項目父項,且我們可能會預期父項會合併所有子項:

@Composable private fun ArticleListItem( openArticle: () -> Unit, addToBookmarks: () -> Unit, ) { Row(modifier = Modifier.clickable { openArticle() }) { // Merges with parent clickable: Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Article thumbnail" ) ArticleDetails() // Defies the merge due to its own clickable: BookmarkButton(onClick = addToBookmarks) } }
當使用者按下 clickable
項目 Row
時,系統會開啟文章。內嵌其中的 BookmarkButton
可用來為文章加上書籤。這個巢狀按鈕會顯示為未合併,而列中其餘的子項內容則會合併:

Row
節點內的清單中包含多個文字。未合併的樹狀圖包含每個 Text
可組合函式的獨立節點。根據設計,部分可組合項不會自動在父項下合併。當子項也正在合併時,父項就無法合併子項,無論是明確設定 mergeDescendants = true
,或是透過可自行合併的元件 (例如按鈕或可點選項目) 合併,瞭解特定 API 的合併方式或不支援合併的情況,有助於您偵錯一些可能發生的異常行為。
當子項元素在父項下構成邏輯且合理的群組時,請使用合併功能。不過,如果巢狀子項需要手動調整或移除自己的語意,其他 API 可能更符合您的需求 (例如 clearAndSetSemantics
)。
清除及設定語意
如果需要完全清除或覆寫語意資訊,可以使用功能強大的 clearAndSetSemantics
API。
如果元件需要清除自身和子項的語意,請使用此 API 搭配空 lambda。當必須覆寫其語意時,請在 lambda 中加入新內容。
請注意,使用空 lambda 清除時,系統不會將清除的語意傳送給使用這類資訊的任何使用者,例如無障礙功能、自動填入或測試。使用 clearAndSetSemantics{/*semantic information*/}
覆寫內容時,新語意會取代元素及其子系的所有舊語意。
以下是自訂切換按鈕元件的示例,以含有圖示和文字的可互動資料列表示:
// Developer might intend this to be a toggleable. // Using `clearAndSetSemantics`, on the Row, a clickable modifier is applied, // a custom description is set, and a Role is applied. @Composable fun FavoriteToggle() { val checked = remember { mutableStateOf(true) } Row( modifier = Modifier .toggleable( value = checked.value, onValueChange = { checked.value = it } ) .clearAndSetSemantics { stateDescription = if (checked.value) "Favorited" else "Not favorited" toggleableState = ToggleableState(checked.value) role = Role.Switch }, ) { Icon( imageVector = Icons.Default.Favorite, contentDescription = null // not needed here ) Text("Favorite?") } }
雖然圖示和文字含有某些語意資訊,但兩者並未共同表示這個元件可切換。您必須提供元件的其他資訊,因此合併是不夠的。
由於上述程式碼片段會建立自訂切換元件,因此您需要新增切換功能,以及 stateDescription
、toggleableState
和 role
語意。這樣一來,您就能使用元件狀態和相關聯的動作,例如 TalkBack 會朗讀「輕觸兩下即可切換」而非「輕觸兩下即可啟用」。
只要清除原始語意並設定更具描述性的新語意,無障礙服務現在就能瞭解這是可切換狀態的切換元件。
使用 clearAndSetSemantics
時,請考量下列事項:
- 由於服務在設定此 API 時不會收到任何資訊,因此建議您謹慎使用。
- AI 服務專員和類似服務可能會使用語意資訊來瞭解螢幕,因此只有在必要時才應清除。
- 您可以在 API lambda 中設定自訂語意。
- 修飾符的順序很重要,這個 API 會清除套用修飾符後的所有語意,不論其他合併策略為何。
隱藏語意
在某些情況下,元素不需要傳送至無障礙服務,因為其額外資訊對無障礙功能來說可能多餘,或是純粹是視覺裝飾性元素,且不具互動性。在這種情況下,您可以使用 hideFromAccessibility
API 隱藏元素。
以下範例顯示可能需要隱藏的元件:跨越元件的多餘浮水印,以及用於裝飾性區隔資訊的字元。
@Composable fun WatermarkExample( watermarkText: String, content: @Composable () -> Unit, ) { Box { WatermarkedContent() // Mark the watermark as hidden to accessibility services. WatermarkText( text = watermarkText, color = Color.Gray.copy(alpha = 0.5f), modifier = Modifier .align(Alignment.BottomEnd) .semantics { hideFromAccessibility() } ) } } @Composable fun DecorativeExample() { Text( modifier = Modifier.semantics { hideFromAccessibility() }, text = "A dot character that is used to decoratively separate information, like •" ) }
在此使用 hideFromAccessibility
可確保水印和裝飾圖案不會顯示在無障礙服務中,但仍可保留其語意,供其他用途使用,例如測試。
用途細目
以下是用途摘要,可協助您瞭解如何清楚區分先前的 API:
- 當內容不供無障礙服務使用時:
- 如果內容可能只是裝飾性或重複性內容,但仍須測試,請使用
hideFromAccessibility
。 - 如需為所有服務清除父項和子項語意,請使用
clearAndSetSemantics{}
搭配空 lambda。 - 當需要手動設定元件的語意時,請在 lambda 內使用
clearAndSetSemantics{/*content*/}
與內容。
- 如果內容可能只是裝飾性或重複性內容,但仍須測試,請使用
- 內容應視為一個實體,且需要所有子項的資訊才能完整:
- 使用合併語意子項。

為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- Compose 中的無障礙功能
- [Compose 中的 Material Design 2][19]
- 測試 Compose 版面配置