es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Por qué se aplica el alto y ancho del modificador de la disposición personalizada a su hijo? ¿Cómo se puede evitar?

He creado un diseño personalizado en Jetpack Compose para alinear los elementos de forma circular. He notado algo extraño, o no sé si me he saltado algo en la documentación de Android. Así que, cada vez que aplico ancho y altura o cualquiera de los dos al modificador de Layout, los elementos hijos obtienen ese ancho o altura. ¿Cómo puedo evitarlo, usarlo solo para el padre pero no para los hijos?

Aquí tienes la salida.



Aquí está el código:

@Composable
fun CircularRevealMenu(
    modifier: Modifier,
    contentPadding: Dp = 16.dp,
    circleRadius: () -> Float,
    content: @Composable () -> Unit
) {
    val configuration = LocalConfiguration.current

    Layout(content = content, modifier = modifier) { children, constraints ->
        val screenWidth = configuration.screenWidthDp.dp.toPx() * circleRadius()

        val placeables = children.map { it.measure(constraints) }

        val maxItemHeight = placeables.maxOf {
            it.height
        }
        val maxItemWidth = placeables.maxOf {
            it.width
        }

        val gap = 90 / placeables.size
        val radiusOffset = (max(maxItemHeight, maxItemWidth) / 2) + contentPadding.toPx()
        val radius = screenWidth - radiusOffset
        val offset = 180 - gap / 2f

        layout(screenWidth.toInt(), screenWidth.toInt()) {
            for (i in placeables.indices) {
                val radians = Math.toRadians((offset - (gap * i)).toDouble())
                placeables[i].placeRelative(
                    x = (cos(radians) * radius + screenWidth).toInt() - placeables[i].width / 2,
                    y = (sin(radians) * radius + 0).toInt() - placeables[i].height / 2
                )
            }
        }
    }
}

enum class CircularMenuStates { Collapsed, Expanded }

@Preview(showBackground = true)
@Composable
fun PreviewCircularMenu() {
    CircularRevealMenu(modifier = Modifier, circleRadius = { 1f }) {
        Text(text = "Item 1")
        Text(text = "Item 2")
        Text(text = "Item 3")
        Text(text = "Item 4")
    }
}
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para evitar que los elementos secundarios de un diseño reciban los modificadores de ancho o alto aplicados al elemento principal, es necesario utilizar el modificador fillMaxSize() en lugar de fillMaxWidth() o fillMaxHeight(). fillMaxSize() solo se aplicará al elemento principal y no a sus elementos secundarios.

    Aquí tienes una versión actualizada del código que utiliza fillMaxSize():

    @Composable
    fun CircularRevealMenu(
        modifier: Modifier,
        contentPadding: Dp = 16.dp,
        circleRadius: () -> Float,
        content: @Composable () -> Unit
    ) {
        val configuration = LocalConfiguration.current
    
        Layout(content = content, modifier = modifier.fillMaxSize()) { children, constraints ->
            val screenWidth = configuration.screenWidthDp.dp.toPx() * circleRadius()
    
            val placeables = children.map { it.measure(constraints) }
    
            val maxItemHeight = placeables.maxOf {
                it.height
            }
            val maxItemWidth = placeables.maxOf {
                it.width
            }
    
            val gap = 90 / placeables.size
            val radiusOffset = (max(maxItemHeight, maxItemWidth) / 2) + contentPadding.toPx()
            val radius = screenWidth - radiusOffset
            val offset = 180 - gap / 2f
    
            layout(screenWidth.toInt(), screenWidth.toInt()) {
                for (i in placeables.indices) {
                    val radians = Math.toRadians((offset - (gap * i)).toDouble())
                    placeables[i].placeRelative(
                        x = (cos(radians) * radius + screenWidth).toInt() - placeables[i].width / 2,
                        y = (sin(radians) * radius + 0).toInt() - placeables[i].height / 2
                    )
                }
            }
        }
    }
    

    Con este cambio, los elementos secundarios ya no heredarán los modificadores de ancho o alto aplicados al elemento principal.

Comments are closed.