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?
3 Réponses :
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) )
backgroundColor
est également utilisé à deux endroits. 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 .
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.
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)
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