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

視覚的な手がかりを提供してフォーカスを簡単に可視化

マテリアル テーマのすべてのフォーカス可能な要素には、すでにテーマに合ったフォーカス スタイルが用意されていますが、フォーカスされている要素を見つけやすくするために、視覚要素の追加が必要になることがあります。要素の枠線を、背景とのコントラストがはっきりした色に変更することをおすすめします。

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

この例では、remember を使用して再コンポーズ後の枠線の色を保存し、要素がフォーカスを得たり失ったりするたびに、要素の輪郭が更新されます。

高度なビジュアル キューを実装する

Jetpack Compose を使用すると、UI に合った洗練された高度なビジュアル キューを作成することもできます。

  1. まず、UI に表示するキューを視覚的に描画する IndicationInstance を作成します。
    private class MyHighlightIndicationInstance(isEnabledState: State<Boolean>) :
        IndicationInstance {
        private val isEnabled by isEnabledState
        override fun ContentDrawScope.drawIndication() {
            drawContent()
            if (isEnabled) {
                drawRect(size = size, color = Color.White, alpha = 0.2f)
            }
        }
    }
  2. 次に、Indication を作成し、フォーカスされた状態を記憶します。
    class MyHighlightIndication : Indication {
        @Composable
        override fun rememberUpdatedInstance(interactionSource: InteractionSource):
            IndicationInstance {
            val isFocusedState = interactionSource.collectIsFocusedAsState()
            return remember(interactionSource) {
                MyHighlightIndicationInstance(isEnabledState = isFocusedState)
            }
        }
    }
  3. indication() 修飾子を使用して、IndicationInteractionSource の両方を UI に追加します。
    val highlightIndication = remember { MyHighlightIndication() }
    var interactionSource = remember { MutableInteractionSource() }
    
    Card(
        modifier = Modifier
            .clickable(
                interactionSource = interactionSource,
                indication = highlightIndication,
                enabled = true,
                onClick = { }
            )
    ) {}

フォーカスの状態を理解する

通常、フォーカスの状態が変化するたびに、FocusEvent がツリーに対して起動され、focusable() 修飾子の親は onFocusChanged() 修飾子を使用してそのツリーをリッスンできます。

フォーカスの状態を把握する必要がある場合は、次の API を onFocusChanged 修飾子と組み合わせて使用できます。

  • isFocused は、修飾子がアタッチされているコンポーザブルがフォーカスされている場合、true を返します。
  • hasFocus の動作は isFocused と同様ですが、大きな違いがあります。現在の要素のみをチェックするのではなく、要素またはその子の一つがフォーカスされているかどうかを確認します。
  • isCaptured は、フォーカスが保持されるたびに true を返します。たとえば、TextField に誤ったデータが含まれているため、他の要素にフォーカスしてもフォーカスはクリアされません。

これらのフィールドは次のとおりです。

Modifier.onFocusChanged {
    val isFocused = it.isFocused
    val hasFocus = it.hasFocus
    val isCaptured= it.isCaptured
}