ユーザーがハードウェア キーボードまたは D-pad を使用して複雑なユーザー インターフェースを操作する場合、画面の異なるセクション間を頻繁に移動します。たとえば、サイド ナビゲーション レールからコンテンツ リストにジャンプし、アイテムを操作してから、元に戻ります。フォーカスの復元を使用すると、コンテナは以前にフォーカスされた子要素を記憶し、フォーカスがコンテナに戻ったときにその要素にフォーカスを復元できます。
スクロール可能なコンテナでフォーカスを復元する
Jetpack Compose では、LazyColumn、LazyRow、LazyVerticalGrid などのスクロール可能なコンテナが自動的にフォーカス グループとして機能します。遅延リストまたはグリッドでフォーカスの復元を有効にするには、focusRestorer 修飾子をアタッチします。
LazyColumn( modifier = Modifier.focusRestorer() ) { items(items) { item -> Button(onClick = { /* Handle click */ }) { Text(item) } } }
フォーカスが LazyColumn から外れると、コンテナはアクティブだったアイテムを記録します。ユーザーがリストに戻ると、フォーカスは先頭に戻るのではなく、そのアイテムに復元されます。
Row と Column でフォーカスを復元する
遅延レイアウト コンテナとは異なり、Row や Column などの標準のスクロール不可レイアウト コンテナは、デフォルトではフォーカス境界を確立しません。これらはフォーカス エントリ イベントを独自にインターセプトしないため、focusRestorer 修飾子を適用するだけでは不十分です。
Row または Column でフォーカスの復元を有効にするには、focusGroup と focusRestorer を組み合わせます。
Row( modifier = Modifier .focusGroup() .focusRestorer() ) { Button(onClick = { /* Action 1 */ }) { Text("First item") } Button(onClick = { /* Action 2 */ }) { Text("Second item") } Button(onClick = { /* Action 3 */ }) { Text("Third item") } }
フォールバック フォーカス ターゲットを指定する
フォーカスが初めてコンテナに入ったとき、以前にフォーカスされた子は存在しません。Compose は、デフォルトのフォーカス順序に従って、フォーカスする子を決定します。
最初のエントリでフォーカスを受け取る子をカスタマイズするには、フォールバック FocusRequester を focusRestorer に渡します(以前の Compose バージョンでは、FocusRequester を返すラムダを渡します)。
val firstItemRequester = remember { FocusRequester() } LazyColumn( modifier = Modifier.focusRestorer(firstItemRequester) ) { itemsIndexed(items) { index, item -> val itemModifier = if (index == 0) { Modifier.focusRequester(firstItemRequester) } else { Modifier } Button( onClick = { /* Handle click */ }, modifier = itemModifier ) { Text(item) } } }
以前にフォーカスされた子がない場合(またはフォーカスの復元に失敗した場合)、Compose は関連付けられたフォールバック ターゲットにフォーカスを移動します。
ナビゲーション コンポーネントで選択したアイテムにフォーカスを合わせる
NavigationRail、NavigationBar、NavigationDrawer、TabRow などのナビゲーション コンポーネントでは、ユーザーはコンテンツ領域からコンポーネントに入るときに、現在選択されているデスティネーションにフォーカスが移動することを期待します。
Modifier.focusGroup() と focusProperties を組み合わせて onEnter プロパティ(以前の Compose バージョンでは enter)を設定することで、アクティブなデスティネーションにフォーカスを合わせることができます。
val (homeRequester, searchRequester, settingsRequester) = remember { FocusRequester.createRefs() } val selectedRequester = when (currentDestination) { "home" -> homeRequester "search" -> searchRequester "settings" -> settingsRequester else -> homeRequester } NavigationRail( modifier = modifier .focusProperties { // Redirect focus to the selected item when focus enters the navigation rail onEnter = { selectedRequester.requestFocus() } } .focusGroup() ) { NavigationRailItem( selected = currentDestination == "home", onClick = { onNavigate("home") }, icon = { Icon(Icons.Default.Home, contentDescription = "Home") }, label = { Text("Home") }, modifier = Modifier.focusRequester(homeRequester) ) NavigationRailItem( selected = currentDestination == "search", onClick = { onNavigate("search") }, icon = { Icon(Icons.Default.Search, contentDescription = "Search") }, label = { Text("Search") }, modifier = Modifier.focusRequester(searchRequester) ) NavigationRailItem( selected = currentDestination == "settings", onClick = { onNavigate("settings") }, icon = { Icon(Icons.Default.Settings, contentDescription = "Settings") }, label = { Text("Settings") }, modifier = Modifier.focusRequester(settingsRequester) ) }
画面遷移間でフォーカスを復元する
ユーザーがアイテムをクリックして詳細画面に移動し、その後 [戻る] ボタンまたはジェスチャーを使用して戻ったときに、クリックしたアイテムにフォーカスを戻すことができます。
画面遷移間でフォーカスを保持して復元するには:
- コンテナを
FocusRequesterに関連付けます。 - ナビゲーション イベントをトリガーする前に、コンテナの
FocusRequesterでsaveFocusedChild()を呼び出します。 - ユーザーが画面に戻ったときに、コンテナの初期フォーカスをリクエストするか、
restoreFocusedChild()を呼び出します。
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- フォーカス ターゲット
- フォーカス移動順序
- フォーカス ターゲットをグループ化する
- プログラムでフォーカスをリクエストする
- フォーカスを移動、クリアする