ユーザーがハードウェア キーボードや D-pad を使用して複雑なユーザー インターフェースを操作する場合、画面のさまざまなセクション間を頻繁に移動します。たとえば、サイド ナビゲーション レールからコンテンツ リストに移動し、アイテムを操作してから戻るなどです。フォーカスの復元を使用すると、コンテナは以前にフォーカスされた子要素を記憶し、フォーカスがコンテナに戻ったときにその要素にフォーカスを復元できます。
スクロール可能なコンテナのフォーカスを復元する
Jetpack Compose では、LazyColumn、LazyRow、LazyVerticalGrid などのスクロール可能なコンテナは、自動的にフォーカス グループとして機能します。遅延リストまたはグリッドでフォーカス復元を有効にするには、focusRestorer 修飾子を付加します。
LazyColumn( modifier = Modifier.focusRestorer() ) { items(items) { item -> Button(onClick = { /* Handle click */ }) { Text(item) } } }
フォーカスが LazyColumn を離れると、コンテナはアクティブだったアイテムを記録します。ユーザーがリストに戻ると、先頭からではなく、そのアイテムにフォーカスが復元されます。
行と列のフォーカスを復元する
遅延レイアウト コンテナとは異なり、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 がオフになっている場合はリンクテキストが表示されます
- フォーカス ターゲット
- フォーカス移動順序
- フォーカス ターゲットをグループ化する
- プログラムでフォーカスをリクエストする
- フォーカスを移動してクリアする