要素のデフォルトのフォーカス動作をオーバーライドすることが必要となる場合がある 画面に表示されるようになりましたたとえば、コンポーザブルをグループ化して、 特定のコンポーザブルにフォーカスし、明示的にフォーカスをリクエストする。 フォーカスをキャプチャまたは解放したり、開始時や終了時にフォーカスをリダイレクトしたりできます。この セクションでは、デフォルトと異なる場合にフォーカス動作を変更する方法について説明します。 できます。
フォーカス グループで一貫したナビゲーションを実現する
Jetpack Compose が、正しい次のアイテムをすぐに推測しないことがあります。
タブ形式ナビゲーション(特にタブなどの複雑な親 Composables
の場合)
リストが役立ちます
フォーカス検索は通常、Composables
の宣言順序に従いますが、
これは不可能なことがあります。たとえば、プレーヤーの Composables
が
階層は水平方向にスクロール可能なため、完全には表示されません。表示される言語
見てみましょう。
Jetpack Compose は、先頭に最も近い次のアイテムをフォーカスするかどうかを決定することがあります。 テスト画面に進むのではなく、 一方向ナビゲーション:
この例では、開発者がフォーカスを [Chocolates] タブから下の最初の画像に移動し、 [ペストリー] タブ。それまではタブに焦点を合わせ、 最後のタブを開いて、内部コンテンツに注目します。
コンポーザブルのグループがフォーカスを得ることが重要な状況では
前の例のタブ行のように、
focusGroup()
修飾子を持つ親の Composable
:
LazyVerticalGrid(columns = GridCells.Fixed(4)) { item(span = { GridItemSpan(maxLineSpan) }) { Row(modifier = Modifier.focusGroup()) { FilterChipA() FilterChipB() FilterChipC() } } items(chocolates) { SweetsCard(sweets = it) } }
双方向ナビゲーションは、指定された
方向 - 別のグループの要素が完全に非表示の要素よりも近くにある場合
場合は、最も近いものが選択されます。これを回避するには
focusGroup()
修飾子を適用できます。
FocusGroup
は、フォーカスの点でグループ全体が 1 つのエンティティのように見えるようにします。
ただし、グループ自体はフォーカスを取得せず、最も近い子がフォーカスを
集中してください。これにより、ナビゲーションは、完全に表示されていない
グループから退会する前に
この場合、FilterChip
の 3 つのインスタンスがフォーカスされ、
SweetsCard
アイテム(SweetsCards
が完全に見えている場合でも)
一部の FilterChip
は非表示になっている可能性があります。これは、
focusGroup
修飾子が、フォーカス マネージャーにアイテムの表示順序を調整するように指示します
簡単に操作でき、UI と一貫性が保たれます。
focusGroup
修飾子がない場合、FilterChipC
が表示されなかった場合にフォーカスする
ナビゲーションが最後にピックアップされます。ただし、このような修飾子を追加しても、
検出可能な場合のみが、FilterChipB
の直後にフォーカスも取得します。
期待どおりに動作しています。
コンポーザブルをフォーカス可能にする
ボタンやコンポーザブルなど、一部のコンポーザブルは、設計上フォーカス可能です。
clickable
修飾子を付けたものになります。特定のキャンペーンタイプを
フォーカス可能な動作をコンポーザブルに変更するには、focusable
修飾子を使用します。
var color by remember { mutableStateOf(Green) } Box( Modifier .background(color) .onFocusChanged { color = if (it.isFocused) Blue else Green } .focusable() ) { Text("Focusable 1") }
コンポーザブルをフォーカス不可にする
一部の要素が関与すべきでない状況が存在する可能性があります。
焦点を当てますそのようなまれな状況では、canFocus property
を活用できます。
Composable
をフォーカス可能から除外します。
var checked by remember { mutableStateOf(false) } Switch( checked = checked, onCheckedChange = { checked = it }, // Prevent component from being focused modifier = Modifier .focusProperties { canFocus = false } )
FocusRequester
を使用してキーボード フォーカスをリクエストする
特定のリクエストへのレスポンスとして明示的にフォーカスを です。たとえば、再起動を希望するかどうかをユーザーに フォームに必要事項を入力し [はい]をクリックします最初のフィールドに再度フォーカスを 入力できます。
まず、FocusRequester
オブジェクトを
キーボードのフォーカスの移動先となるコンポーザブルを指定します。次のコードでは、
FocusRequester
オブジェクトは、次のように設定することで TextField
に関連付けられます。
Modifier.focusRequester
という修飾子を使用します。
val focusRequester = remember { FocusRequester() } var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it }, modifier = Modifier.focusRequester(focusRequester) )
実際のフォーカス リクエストを送信するには、FocusRequester の requestFocus
メソッドを呼び出します。このメソッドは、Composable
コンテキストの外部で呼び出す必要があります。
(そうしないと、再コンポーズのたびに再実行されます)。次のスニペット
ボタンが押されたときにキーボード フォーカスを移動するようにシステムにリクエストする方法を示します。
クリック:
val focusRequester = remember { FocusRequester() } var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it }, modifier = Modifier.focusRequester(focusRequester) ) Button(onClick = { focusRequester.requestFocus() }) { Text("Request focus on TextField") }
キャプチャしてフォーカスを離す
フォーカスを活用して、ユーザーがアプリに適切なデータを提供できるよう導くことができる たとえば、有効なメールアドレスや電話番号の取得など、 あります。エラー状態はユーザーに状況を知らせますが、 入力ミスが起きるまで そのフィールドに誤った情報を入れて あります。
フォーカスをキャプチャするために、captureFocus()
メソッドを呼び出します。
次のように、代わりに freeFocus()
メソッドを使って解放します。
例:
val textField = FocusRequester() TextField( value = text, onValueChange = { text = it if (it.length > 3) { textField.captureFocus() } else { textField.freeFocus() } }, modifier = Modifier.focusRequester(textField) )
フォーカス修飾子の優先順位
Modifiers
は、子が 1 つしかない要素とみなされるため、キューに入れると
その左側(または一番上)にある各 Modifier
が、その後に続く Modifier
をラップします。
右(または下)に表示されます。つまり、2 つ目の Modifier
は
そのため、2 つの focusProperties
を宣言すると、最上位の
以下のものは一番上にあるため、1 つは機能します。
コンセプトをより明確にするため、次のコードをご覧ください。
Modifier .focusProperties { right = item1 } .focusProperties { right = item2 } .focusable()
この場合、item2
を右フォーカスとして示す focusProperties
は、
前述のものに含まれているため、使用しないでください。したがって、item1
は
もう 1 つは使用します
この方法を利用して、親は次の方法で動作をデフォルトにリセットすることもできます。
FocusRequester.Default
を使用:
Modifier .focusProperties { right = Default } .focusProperties { right = item1 } .focusProperties { right = item2 } .focusable()
親は同じ修飾子チェーンの一部である必要はありません。保護者
コンポーザブルは、子コンポーザブルのフォーカス プロパティを上書きできます。たとえば
ボタンをフォーカス不可にする FancyButton
について考えてみましょう。
@Composable fun FancyButton(modifier: Modifier = Modifier) { Row(modifier.focusProperties { canFocus = false }) { Text("Click me") Button(onClick = { }) { Text("OK") } } }
ユーザーは、canFocus
を true
に設定することで、このボタンを再度フォーカス可能にできます。
FancyButton(Modifier.focusProperties { canFocus = true })
他の Modifier
と同様に、フォーカス関連のものは順序に応じて動作が異なる
宣言します。たとえば、次のようなコードにより、Box
フォーカス可能ですが、FocusRequester
はこのフォーカス可能に関連付けられていません。
フォーカス可能な後に宣言されます。
Box( Modifier .focusable() .focusRequester(Default) .onFocusChanged {} )
focusRequester
は最初の Pod に関連付けられることに
フォーカス可能であるため、この focusRequester
は
最初のフォーカス可能な子です。使用できるものがない場合は、何も参照しません。
ただし、(focusable()
修飾子のおかげで)Box
はフォーカス可能なため、
双方向ナビゲーションを使用できます
別の例として、onFocusChanged()
は、次のいずれかでも機能します。
修飾子は、
focusable()
修飾子または focusTarget()
修飾子。
Box( Modifier .onFocusChanged {} .focusRequester(Default) .focusable() ) |
Box( Modifier .focusRequester(Default) .onFocusChanged {} .focusable() ) |
開始時または終了時にフォーカスをリダイレクト
場合によっては、次のような、非常に具体的なナビゲーションを提供する必要があります このようになります。
これの作成方法について説明する前に、デフォルトの
フォーカス検索の動作が異なります。フォーカス検索が終われば、変更なしで
Clickable 3
の項目に移動し、D-pad(または同等のもの)の DOWN
を押す
矢印キーなど)を押すと、Column
の下に表示されているものにフォーカスが移動します。
グループから出て 右側のグループを無視しますコンバージョン トラッキングが
フォーカス可能な項目がある場合、フォーカスは移動せず、表示されたままになります
Clickable 3
。
この動作を変更して、意図したナビゲーションを実現するには、
focusProperties
修飾子: フォーカスしたときの動作を管理できます
Composable
に入る、または終了します。
val otherComposable = remember { FocusRequester() } Modifier.focusProperties { exit = { focusDirection -> when (focusDirection) { Right -> Cancel Down -> otherComposable else -> Default } } }
特定の Composable
に入るたびに、フォーカスをその中に送ることができます。
UI に 2 つのルールがある場合などに、
最初の列を処理するたびに
フォーカスが 2 番目に切り替わります。
この GIF では、Column
1 でフォーカスが Clickable 3 Composable
に到達すると、
フォーカスされている次のアイテムは別の Column
の Clickable 4
です。この動作
これは、focusDirection
を enter
および exit
と組み合わせることで実現できます。
focusProperties
修飾子内の値。2 人とも、引数として渡されるラムダを
パラメータとしてフォーカスの方向を指定し、
FocusRequester
。このラムダの動作には、次の 3 つがあります。
FocusRequester.Cancel
はフォーカスの継続を停止しますが、
FocusRequester.Default
の動作は変更されません。代わりに
FocusRequester
を別の Composable
にアタッチすると、その部分にフォーカスが移動します。
固有の Composable
。
フォーカスの進行方向を変更する
フォーカスを次の項目や正確な方向に進めるには、
onPreviewKey
修飾子を利用して、LocalFocusManager
を暗黙的に指定し、
moveFocus
修飾子を使用してフォーカスを進めます。
次の例は、フォーカス メカニズムのデフォルトの動作を示しています。
tab
キーの押下が検出されると、フォーカスはフォーカス内の次の要素に進みます
選択します。これは通常構成する必要はありませんが、
システムの内部動作を把握し
確認します。
val focusManager = LocalFocusManager.current var text by remember { mutableStateOf("") } TextField( value = text, onValueChange = { text = it }, modifier = Modifier.onPreviewKeyEvent { when { KeyEventType.KeyUp == it.type && Key.Tab == it.key -> { focusManager.moveFocus(FocusDirection.Next) true } else -> false } } )
このサンプルでは、focusManager.moveFocus()
関数がフォーカスを
指定されたアイテム、または関数パラメータで指定された方向に設定されます。
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- 対応して焦点に集中
- Compose のフォーカス
- フォーカス移動順序を変更する