リアクションして集中する

コンポジション ツリー全体でフォーカスが変化するたびに、Compose はフォーカス イベントを発生させます。このイベントは、親と子の修飾子が監視できます。onFocusChanged 修飾子を使用すると、フォーカス状態の遷移をリッスンし、現在のフォーカス プロパティをクエリして、状態駆動型の UI 更新をトリガーできます。

onFocusChanged でフォーカス状態を監視する

onFocusChanged 修飾子は、要素がフォーカスを取得または喪失するたびに FocusState オブジェクトを提供します。

たとえば、フォーカスの変更を監視して、カスタム コンポーネントの状態を更新できます(要素の枠線の色を変更したり、アニメーションをトリガーしたりするなど)。

var color by remember { mutableStateOf(Color.White) }
Card(
    modifier = Modifier
        .onFocusChanged {
            color = if (it.isFocused) Red else White
        }
        .border(5.dp, color)
) {}

この例では、remember は再コンポーズ間で枠線の色を保存し、要素のフォーカス状態が遷移するたびに枠線の色が更新されます。

FocusState プロパティ

onFocusChanged に渡される FocusState オブジェクトには、次の 3 つの主要なプロパティがあります。

  • isFocused: この修飾子がアタッチされている特定のコンポーザブルが現在アクティブな入力フォーカスを保持している場合は、true を返します。
  • hasFocus: このコンポーザブルまたはその子コンポーザブルのいずれかが現在フォーカスされている場合は、true を返します。これは、内部の子がアクティブになったタイミングを把握する必要がある親コンテナ(カードやツールバーなど)に便利です。
  • isCaptured: フォーカスが現在要素にロックされている場合(captureFocus() を使用したモーダル サブインタラクション中など)に true を返します。キャプチャ中にフォーカスを他の要素に移動しようとしても、フォーカスはクリアされません。
Modifier.onFocusChanged { focusState ->
    val isFocused = focusState.isFocused
    val hasFocus = focusState.hasFocus
    val isCaptured = focusState.isCaptured
}