Surfaces dans Jetpack Compose Glimmer

Appareils XR concernés
Ces conseils vous aident à créer des expériences pour ces types d'appareils XR.
Lunettes Display

Dans Jetpack Compose Glimmer, le composant surface est un composant de base fondamental qui représente une zone visuelle distincte ou une limite physique pour des composants tels que les boutons et les fiches.

Une surface est responsable des propriétés visuelles et physiques suivantes :

  • Découpage : découpe ses enfants selon une forme spécifiée.
  • Bordure : dessine une bordure intérieure pour mettre en évidence la limite du composant. Lorsqu'il est sélectionné, il dessine une bordure plus large avec une mise en évidence.
  • Arrière-plan : applique une couleur d'arrière-plan à la surface.
  • Effets de profondeur : affiche les ombres DepthEffect en fonction de l'état du composant (par exemple, par défaut ou sélectionné).
  • Couleur du contenu : fournit une couleur pour le texte et les icônes à l'intérieur de la surface, calculée par défaut à partir de la couleur d'arrière-plan.
  • États d'interaction : dessine un calque de pression lorsque la surface est enfoncée et une bordure plus large avec une mise en surbrillance lorsqu'elle est sélectionnée.

Exemple : Créer une surface

Le code suivant crée une surface avec un arrière-plan, des bordures par défaut et un écrêtage :

@Composable
fun SurfaceSample() {
    Box(Modifier.surface().padding(horizontal = 24.dp, vertical = 20.dp)) {
        Text("This is a surface")
    }
}

Interaction and Focus

Surfaces aren't focusable by default, so users can't interact with them. In most cases, surfaces should be interactive to let users consistently move focus and navigate between components. You can use the Compose focusable modifer for surfaces that are only intended to be focusable, or the Compose clickable modifer and other modifiers for surfaces that require actions.

You can create a focusable surface by combining a surface modifier with the focusable modifier:

@Composable
fun FocusableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        Modifier.surface(
                // Provide the same interaction source here and to focusable to make sure that
                // surface appears focused when interacted with.
                interactionSource = interactionSource
            )
            .focusable(interactionSource = interactionSource)
            .padding(horizontal = 24.dp, vertical = 20.dp)
    ) {
        Text("This is a focusable surface")
    }
}

Key points about the code

  • Shared interaction source: Both .surface() and .focusable() must share the same interactionSource. This lets the surface react to focus changes.

Similarly, you can create a clickable surface:

@Composable
fun ClickableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        Modifier.surface(
                // Provide the same interaction source here and to clickable to make sure that
                // surface appears focused and pressed when interacted with
                interactionSource = interactionSource
            )
            .clickable(interactionSource = interactionSource, onClick = {})
            .padding(horizontal = 24.dp, vertical = 20.dp)
    ) {
        Text("This is a clickable surface")
    }
}

Points clés concernant le code

  • Source d'interaction partagée : les deux .surface() et .clickable() doit partager le même interactionSource. Cela permet de s'assurer que les états visuels (comme la pression ou la mise au point) sont synchronisés, ce qui permet à la surface de réagir visuellement aux entrées utilisateur.

  • Ordre des modificateurs : l'ordre des modificateurs est essentiel. Parce que .surface() découpe une mise en page et la place avant .clickable() garantit que la cible tactile est limitée à la forme de la surface. Si .clickable() en premier, la zone d'interaction peut s'étendre au-delà des limites visibles et coupées du composant.

SurfaceDepthEffect

La classe SurfaceDepthEffect gère la transition des ombres entre les états d'interaction :

  • depthEffect : effet d'ombre utilisé lorsque la surface est dans son état par défaut.
  • focusedDepthEffect : effet d'ombre utilisé lorsque la surface est sélectionnée.