Reagieren, um den Fokus zu schärfen

Visuelle Hinweise für eine einfachere Visualisierung des Fokus

Während alle fokussierbaren Elemente aus „Material Theme“ bereits einen Fokusstil haben die zum Thema passen, müssen Sie möglicherweise einige visuelle Elemente hinzufügen, fokussiertes Element leichter zu erkennen. Eine gute Lösung wäre, den Rahmen Ihr Element mit einer Farbe versehen, die einen guten Kontrast zum Hintergrund aufweist:

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

In diesem Beispiel wird mit remember die Rahmenfarbe quer durch den neu zusammengesetzt und der Umriss des Elements wird jedes Mal aktualisiert, wenn das Element gewinnen oder verlieren.

Erweiterte visuelle Hinweise implementieren

Mit Jetpack Compose können Sie auch anspruchsvollere visuelle Elemente die besser zu deiner Benutzeroberfläche passen.

  1. Erstellen Sie zuerst ein IndicationInstance, das den gewünschten Hinweis auf Ihrer Benutzeroberfläche visuell darstellt:
    private class MyHighlightIndicationNode(private val interactionSource: InteractionSource) :
        Modifier.Node(), DrawModifierNode {
        private var isFocused = false
    
        override fun onAttach() {
            coroutineScope.launch {
                var focusCount = 0
                interactionSource.interactions.collect { interaction ->
                    when (interaction) {
                        is FocusInteraction.Focus -> focusCount++
                        is FocusInteraction.Unfocus -> focusCount--
                    }
                    val focused = focusCount > 0
                    if (isFocused != focused) {
                        isFocused = focused
                        invalidateDraw()
                    }
                }
            }
        }
    
        override fun ContentDrawScope.draw() {
            drawContent()
            if (isFocused) {
                drawRect(size = size, color = Color.White, alpha = 0.2f)
            }
        }
    }
    
  2. Erstellen Sie als Nächstes ein Indication und merken Sie sich den hervorgehobenen Zustand:
    object MyHighlightIndication : IndicationNodeFactory {
        override fun create(interactionSource: InteractionSource): DelegatableNode {
            return MyHighlightIndicationNode(interactionSource)
        }
    
        override fun hashCode(): Int = -1
    
        override fun equals(other: Any?) = other === this
    }
  3. Fügen Sie der Benutzeroberfläche mit dem indication()-Modifikator sowohl Indication als auch InteractionSource hinzu:
    var interactionSource = remember { MutableInteractionSource() }
    
    Card(
        modifier = Modifier
            .clickable(
                interactionSource = interactionSource,
                indication = MyHighlightIndication,
                enabled = true,
                onClick = { }
            )
    ) {
        Text("hello")
    }

Den Zustand des Fokus verstehen

Im Allgemeinen wird jedes Mal, wenn sich ein Fokusstatus ändert, ein FocusEvent ausgelöst. Baum und die übergeordneten Elemente eines focusable()-Modifikator können ihn mit der Funktion onFocusChanged()-Modifikator.

Wenn Sie den Status des Fokus wissen müssen,können Sie diese APIs zusammen verwenden. mit dem onFocusChanged-Modifikator:

  • isFocused gibt true zurück, wenn die zusammensetzbare Funktion, an die der Modifikator angehängt ist, angehängt ist. ist fokussiert
  • hasFocus funktioniert ähnlich wie isFocused, aber mit einem wesentlichen Unterschied: und nicht nur das aktuelle Element, sondern auch, ob das Element oder eines seiner Kinder sind konzentriert
  • isCaptured gibt immer true zurück, wenn der Fokus gehalten wird. Das passiert bei wenn ein TextField falsche Daten enthält, sodass der Fokus anderen Elementen den Fokus nicht.

Im Folgenden sehen Sie diese Felder:

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