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 d'affichage

Dans Jetpack Compose Glimmer, le surface composant 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 zone de 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 une superposition enfoncée lorsque la surface est enfoncée et une bordure plus large avec une mise en évidence lorsqu'elle est sélectionnée.

Exemple : Créer une surface

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

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

Interaction et sélection

Les surfaces ne sont pas sélectionnables par défaut. Les utilisateurs ne peuvent donc pas interagir avec elles. Dans la plupart des cas, les surfaces doivent être interactives pour permettre aux utilisateurs de déplacer la sélection et de naviguer entre les composants de manière cohérente. Vous pouvez utiliser le modificateur Compose focusable pour les surfaces qui ne sont destinées à être sélectionnables. De même, vous pouvez créer une surface cliquable à l'aide du modificateur clickable Compose. Vous pouvez également utiliser d'autres modificateurs pour les surfaces qui nécessitent des actions.

Le code suivant montre des exemples de surfaces sélectionnables et cliquables :

@Composable
fun FocusableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        modifier = Modifier
            .size(100.dp)
            .surface(interactionSource = interactionSource)
            .focusable(interactionSource = interactionSource),
        contentAlignment = Alignment.Center
    ) {
        Text("Focusable")
    }
}

@Composable
fun ClickableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        modifier = Modifier
            .size(100.dp)
            .surface(interactionSource = interactionSource)
            .focusable(interactionSource = interactionSource)
            .clickable(
                interactionSource = interactionSource,
                indication = null
            ) { /* Handle click action */ },
        contentAlignment = Alignment.Center
    ) {
        Text("Clickable")
    }
}

Points clés concernant le code

  • Source d'interaction partagée pour les surfaces sélectionnables : .surface() et .focusable() doivent partager la même interactionSource. Cela permet à la surface de réagir aux changements de sélection.

  • Source d'interaction partagée pour les surfaces cliquables : .surface() et .clickable() doivent partager la même interactionSource. Cela garantit que les états visuels (comme la pression ou la sélection) sont synchronisés, ce qui permet à la surface de réagir visuellement à l'entrée utilisateur.

  • Ordre des modificateurs : la séquence des modificateurs est essentielle. Étant donné que .surface() découpe une mise en page, le fait de le placer avant .clickable() garantit que la cible tactile est limitée à la forme de la surface. Si .clickable() apparaît en premier, la zone d'interaction peut s'étendre au-delà des limites visibles et dé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.