フォーカス移動順序の変更

デフォルトのフォーカス移動順序セクションでは、1 次元(tab キー)ナビゲーションと 2 次元(矢印キー)ナビゲーションの両方で、Compose がフォーカス移動動作を要素に自動的に追加する仕組みについて説明しました。場合によっては、このデフォルトの動作をオーバーライドし、必要な走査順序をより明示的に指定する必要があります。

1 次元の移動順序をオーバーライドする

1 次元ナビゲーションのデフォルトのフォーカス移動順序を変更するには、フォーカス可能なコンポーザブルごとに 1 つの参照を作成します。

val (first, second, third, fourth) = remember { FocusRequester.createRefs() }

次に、focusRequester 修飾子を使用して、それぞれをコンポーザブルに関連付けます。

Column {
    Row {
        TextButton({}, Modifier.focusRequester(first)) { Text("First field") }
        TextButton({}, Modifier.focusRequester(third)) { Text("Third field") }
    }

    Row {
        TextButton({}, Modifier.focusRequester(second)) { Text("Second field") }
        TextButton({}, Modifier.focusRequester(fourth)) { Text("Fourth field") }
    }
}

focusProperties 修飾子を使用して、カスタムの移動順序を指定できるようになりました。

Column {
    Row {
        TextButton(
            {},
            Modifier
                .focusRequester(first)
                .focusProperties { next = second }
        ) {
            Text("First field")
        }
        TextButton(
            {},
            Modifier
                .focusRequester(third)
                .focusProperties { next = fourth }
        ) {
            Text("Third field")
        }
    }

    Row {
        TextButton(
            {},
            Modifier
                .focusRequester(second)
                .focusProperties { next = third }
        ) {
            Text("Second field")
        }
        TextButton(
            {},
            Modifier
                .focusRequester(fourth)
                .focusProperties { next = first }
        ) {
            Text("Fourth field")
        }
    }
}

2 次元の移動順序をオーバーライドする

矢印キーを使用して、2 次元ナビゲーションのフォーカス移動順序を細かく制御することもできます。各要素に対して、focusProperties 修飾子を追加し、上下左右のアイテムを指定することで、各方向のデフォルトのナビゲーション デスティネーションをオーバーライドできます。

TextButton(
    onClick = {},
    modifier = Modifier
        .focusRequester(fourth)
        .focusProperties {
            down = third
            right = second
        }
) {}

この手法は、キーボードの矢印を効果的に使用するだけでなく、有線コントローラやワイヤレス コントローラの D-pad やスティックでも機能します。