33
votes

Quand dois-je utiliser Android Jetpack Compose Surface Composable?

il y a Surface composable dans le composi qui représente un surface du matériau . Une surface vous permet de configurer des choses comme la couleur ou la bordure d'arrière-plan, mais il semble que la même chose puisse être fait en utilisant Modificateurs . Quand dois-je utiliser la surface composable et quels sont les avantages qu'il me donne?


0 commentaires

3 Réponses :


54
votes

Surface Composable rend le code plus facile en plus d'indiquer explicitement que le code utilise un Surface matérielle . Voyons un exemple:

val shape = RoundedCornerShape(8.dp)
val shadowElevationPx = with(LocalDensity.current) { 2.dp.toPx() }
val backgroundColor = MaterialTheme.colors.primarySurface

Text(
    text = "example",
    color = contentColorFor(backgroundColor),
    modifier = Modifier
        .graphicsLayer(shape = shape, shadowElevation = shadowElevationPx)
        .background(backgroundColor, shape)
        .border(1.dp, MaterialTheme.colors.secondary, shape)
        .padding(8.dp)
)
  • La chaîne des modificateurs est assez grande et il n'est pas évident qu'elle implémente une surface matériale
  • Je dois déclarer une variable pour la forme et la transmettre en trois modificateurs différents
  • Il utilise contenucolorfor pour comprendre La couleur du contenu tandis que la surface le fait sous le capot. En conséquence, le backgroundColor est également utilisé à deux endroits.
  • Je dois calculer l'élévation des pixels
  • Surface Ajuste les couleurs pour l'élévation (en cas de thème sombre) Selon la conception du matériau . Si vous voulez le même comportement, il doit être géré manuellement.

Pour la liste complète des fonctionnalités de surface, il est préférable de jeter un œil à la Documentation .


1 commentaires

Le blocage de la propagation tactile pourrait peut-être être le rôle le plus important de la surface, par rapport aux autres vues / composiables de contenu.



5
votes

La surface est l'équivalent de CardView dans le système de vue.
Par Surface , vous pouvez définir une élévation pour la vue (notez que ce n'est pas la même chose avec modificateur.shadow)


0 commentaires

0
votes

Surface est une box avec un modificateur.surface () et des couleurs et une élévation du matériau, il vérifie l'élévation des ancêtres pour être toujours allumé en haut d'eux, et ne surcharger que sous le blocage de la propagation tactile derrière la surface avec Poininput (unité) {} .

Surface(
    modifier = Modifier.size(200.dp),
    onClick = {}) {
    Column(
        modifier = Modifier
            .size(50.dp)
            .background(Color.Red, RoundedCornerShape(6.dp))
    ) {}
}

Spacer(modifier = Modifier.height(20.dp))

Surface(
    modifier = Modifier.size(200.dp),
    onClick = {}) {
    Column(
        modifier = Modifier
            .size(50.dp)
            .background(Color.Red, RoundedCornerShape(6.dp))
    ) {
        Column(
            modifier = Modifier
                .size(50.dp)
                .background(Color.Green, RoundedCornerShape(6.dp))
        ) {}

    }
}

Spacer(modifier = Modifier.height(20.dp))

Box(
    modifier = Modifier.size(200.dp)
) {
    Column(
        modifier = Modifier
            .size(50.dp)
            .background(Color.Red, RoundedCornerShape(6.dp))
    ) {
        Column(
            modifier = Modifier
                .size(50.dp)
                .background(Color.Green, RoundedCornerShape(6.dp))
        ) {}

    }
}

et modificateur.surface ()

private fun Modifier.surface(
    shape: Shape,
    backgroundColor: Color,
    border: BorderStroke?,
    elevation: Dp
) = this.shadow(elevation, shape, clip = false)
    .then(if (border != null) Modifier.border(border, shape) else Modifier)
    .background(color = backgroundColor, shape = shape)
    .clip(shape)

Une autre chose intéressante est que c'est box avec propagateminonstraints = true paramètre qui oblige d'abord le descendant mêmes contraintes ou dimensions minimales

@Composable
fun Surface(
    modifier: Modifier = Modifier,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(color),
    border: BorderStroke? = null,
    elevation: Dp = 0.dp,
    content: @Composable () -> Unit
) {
    val absoluteElevation = LocalAbsoluteElevation.current + elevation
    CompositionLocalProvider(
        LocalContentColor provides contentColor,
        LocalAbsoluteElevation provides absoluteElevation
    ) {
        Box(
            modifier = modifier
                .surface(
                    shape = shape,
                    backgroundColor = surfaceColorAtElevation(
                        color = color,
                        elevationOverlay = LocalElevationOverlay.current,
                        absoluteElevation = absoluteElevation
                    ),
                    border = border,
                    elevation = elevation
                )
                .semantics(mergeDescendants = false) {}
                .pointerInput(Unit) {},
            propagateMinConstraints = true
        ) {
            content()
        }
    }
}

dans le premier exemple sur Surface Forces Colonne pour avoir 200.dp taille même s'il a modificateur.size (50.dp) .

Dans le deuxième exemple Box à l'intérieur colonne code > a une taille 50.dp car ce n'est pas un descendant direct de Surface .

Dans le troisième exemple si nous remplaçons Surface ( Box par propagateMinconstraints VRUE ) avec Box Il permet aux descendants directs d'utiliser ses propres contraintes ou dimensions.

 Entrez la description de l'image ici


0 commentaires