您可以使用 focusGroup 修飾符,將多個焦點目標分組。分組可讓您管理焦點階層、隔離邏輯 UI 區域 (例如工具列、對話方塊動作或資訊卡清單),並在焦點進入或離開區域時攔截。
焦點團體概念:進入、退出和預設遍歷
焦點群組會在其子焦點目標周圍建立一致的導覽邊界。如要瞭解焦點如何跨越這個邊界,必須掌握兩個重要概念:
- Enter:當焦點從焦點群組外的任何元素,轉移至群組內的元素時,就會發生這個事件。
- Exit:當焦點離開群組的最後一個內部元素,並轉換至外部焦點目標時,就會發生此事件。
預設焦點遍歷行為
根據預設,當焦點群組從外部接收焦點時:
- 進入群組:Compose 會自動選取內部子項焦點目標。如果是一維 (Tab) 導覽,系統會按照視覺外觀順序選取第一個子項。如果是二維 (方向鍵或 D-pad) 導覽,系統會選取幾何上最接近傳入方向的子項。
- 在群組內瀏覽:重複按下瀏覽鍵,可在群組內同層級的焦點目標之間移動焦點。
- 離開群組:使用者瀏覽完群組內最後一個焦點目標後,下次按下按鍵就會離開群組,並將焦點移至群組外的相鄰焦點目標。
自訂焦點項目重新導向
在許多 UI 設計中,預設的進入目標 (例如外觀順序中的第一個子項) 對使用者來說並不是最符合邏輯或最方便的選擇。
用途
假設確認對話方塊左側有「取消」按鈕,右側有主要「確認」按鈕。使用者從表單欄位向下瀏覽至按鈕列時:
- 預設行為:焦點會落在「取消」上,因為這是視覺外觀順序中的第一個按鈕。
- 預期行為:由於「確認」是主要建議動作,因此當您從焦點順序中較早的位置進入按鈕群組時,可能會希望焦點直接落在「確認」上,同時仍允許使用者視需要按下向左鍵選取「取消」。
其他常見用途包括:
- 進入
TabRow時,直接將焦點移至目前選取的分頁。 - 進入媒體播放列時,直接將焦點移至「播放 / 暫停」控制項。
使用 onEnter 和 FocusRequester 實作
如要在進入焦點團體時重新導向焦點,請按照下列步驟操作:
- 將
focusGroup修飾符套用至包含相關焦點目標的父項容器。 - 將
focusProperties修飾符套用至容器,並設定onEnter回呼。 - 在
onEnter回呼 (範圍限定為FocusEnterExitScope) 中,使用focusRequester對與偏好預設子項相關聯的FocusRequester呼叫requestFocus()。
val defaultChildRequester = remember { FocusRequester() } Row( modifier = Modifier .focusGroup() .focusProperties { // Intercept entry into this group and redirect focus to the primary action onEnter = { defaultChildRequester.requestFocus() } } ) { Button(onClick = { /* Cancel action */ }) { Text("Cancel") } Button( onClick = { /* Confirm action */ }, modifier = Modifier.focusRequester(defaultChildRequester) ) { Text("Confirm (Default)") } }
在 onEnter 和 onExit 中,您也可以呼叫 cancelFocusChange(),完全封鎖跨邊界的焦點轉換,或檢查 requestedFocusDirection,根據使用者是否使用 Tab、Down 或 Left 進行導覽,自訂轉送。
可捲動容器預設為焦點群組
在 Jetpack Compose 中,LazyRow、LazyColumn 和 LazyVerticalGrid 等可捲動容器會自動做為焦點群組。您不需要明確對其套用 focusGroup 修飾符,即可設定 onEnter 或 onExit 回呼。