Wann sollte ich Android Jetpack Compose Surface Composable verwenden?

Lesezeit: 3 Minuten

Es gibt Auftauchen composable in Jetpack Compose, das a darstellt Materialoberfläche. Eine Oberfläche ermöglicht es Ihnen, Dinge wie Hintergrundfarbe oder Rahmen einzurichten, aber es scheint, dass das Gleiche mit der Verwendung möglich ist Modifikatoren. Wann sollte ich das Surface Composable verwenden und welche Vorteile bietet es mir?

Benutzeravatar von Valeriy Katkov
Walerij Katkow

Auftauchen composable macht den Code einfacher und zeigt explizit an, dass der Code a verwendet Materialoberfläche. Sehen wir uns ein Beispiel an:

Surface(
    color = MaterialTheme.colors.primarySurface,
    border = BorderStroke(1.dp, MaterialTheme.colors.secondary),
    shape = RoundedCornerShape(8.dp),
    elevation = 8.dp
) {
    Text(
        text = "example",
        modifier = Modifier.padding(8.dp)
    )
}

und das Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Dasselbe Ergebnis kann ohne Surface erzielt werden:

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)
)

hat aber ein paar nachteile:

  • Die Modifikatorkette ist ziemlich groß und es ist nicht offensichtlich, dass sie eine Materialoberfläche implementiert
  • Ich muss eine Variable für die Form deklarieren und sie an drei verschiedene Modifikatoren übergeben
  • Es verwendet contentColorFor um die Inhaltsfarbe herauszufinden, während Surface dies unter der Haube erledigt. Als Ergebnis die backgroundColor wird auch an zwei Stellen verwendet.
  • Ich muss die Höhe in Pixel berechnen
  • Surface passt Farben für die Höhe an (im Falle eines dunklen Themas) nach Materialdesign. Wenn Sie das gleiche Verhalten wünschen, sollte es manuell gehandhabt werden.

Für die vollständige Liste der Surface-Funktionen werfen Sie am besten einen Blick auf die Dokumentation.

  • Das Blockieren der Berührungsausbreitung könnte vielleicht die wichtigste Rolle des Surface im Vergleich zu anderen Inhaltsansichten/Composables sein.

    – Anm

    13. September 2021 um 14:44 Uhr

Oberfläche ist das Äquivalent von CardView im Sichtsystem.
Durch Surfacekönnen Sie die Höhe für die Ansicht festlegen (beachten Sie, dass dies bei Modifier.shadow nicht dasselbe ist).

Benutzeravatar von Thracian
Thrakisch

Surface ist ein Box mit einer Modifier.surface() und Materialfarben und Höhe, es überprüft die Höhe der Vorfahren, um immer über ihnen zu sein, und überlastet nur unten, um die Berührungsausbreitung hinter der Oberfläche zu blockieren pointerInput(Unit) {}.

@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()
        }
    }
}

Und Modifier.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)

Eine andere interessante Sache ist es Box mit propagateMinConstraints = true Parameter, der den ersten Nachkommen dazu zwingt, dieselben Mindestbeschränkungen oder -abmessungen zu haben

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))
    ) {
        Box(
            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))
    ) {
        Box(
            modifier = Modifier
                .size(50.dp)
                .background(Color.Green, RoundedCornerShape(6.dp))
        )

    }
}

Im ersten Beispiel auf Surface Kräfte Column haben 200.dp Größe, obwohl es hat Modifier.size(50.dp).

Im zweiten Beispiel Box Innerhalb Column hat eine Größe von 50.dp, weil es kein direkter Nachkomme von ist Surface.

Im dritten Beispiel ersetzen wir Surface(Box mit propagateMinConstraints true) mit Box es erlaubt direkten Nachkommen, ihre eigenen Beschränkungen oder Dimensionen zu verwenden.

Geben Sie hier die Bildbeschreibung ein

1436440cookie-checkWann sollte ich Android Jetpack Compose Surface Composable verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy