android - Cambiar la dirección del diseño de un Composable

CorePress2024-01-25  10

Quiero establecer una dirección de un elemento componible específico para que sea RTL


@Composable
fun ViewToBeChanged() {
  Row {
     Image()
     Column {
        Text("Title")
        Text("Subtitle")
    }
  }
}

¿Es posible?

La documentación de Jetpack Compose Layout menciona LocalLayoutDirection

Cambie la dirección del diseño de un elemento componible cambiando la composición LocalLayoutDirectionLocal.

Pero no tengo idea de cómo usarlo en un elemento componible para que surta efecto.

Si no desea cambiar a diseños RTL pero solo desea dibujar el diseño de una manera diferente, de arriba a abajo (como Columna) o de principio a fin (como Fila), entonces la flexibilidad de constraintLayout podría ser lo que estás buscando. Hay una implementación de redacción: desarrollador.android.com/jetpack/androidx/releases/…

- Peter F.

24 de junio de 2022 a las 11:41



------------------------------------

Puedes utilizar CompositionLocalProvider para proporcionar un LocalLayoutDirection personalizado.

Algo como:

CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl ) {
    Column(Modifier.fillMaxWidth()) {
        Text("Title")
        Text("Subtitle")
    }
}

0



------------------------------------

Como no tenía tu imagen, modifiqué tu elemento componible para:

@Composable
fun ViewToBeChanged() {
  Row {
    Text("Foo", modifier = Modifier.padding(end = 8.dp))

    Column {
      Text("Title")
      Text("Subtitle")
    }
  }
}

Eso nos da:

Una forma de cambiar a RTL es utilizar CompositionLocalProvider y LocalLayoutDirection:

@Composable
fun RtlView() {
  CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
    Row {
      Text("Foo", modifier = Modifier.padding(end = 8.dp))

      Column {
        Text("Title")
        Text("Subtitle")
      }
    }
  }
}

Aquí estamos diciendo que estamos anulando CompositionLocal para la dirección de diseño para el contenido de la lambda final proporcionada a CompositionLocalProvider(). Esto nos da:

Esto cambia la dirección de diseño utilizada por esta rama del árbol componible, para los propios elementos componibles. El inglés sigue siendo un idioma LTR, por lo que el texto no se ve afectado.



------------------------------------

Como generalización de las otras respuestas, si esto es necesario en diferentes Composables podemos definir elsiguiente

@Composable
fun RightToLeftLayout(content: @Composable () -> Unit) {
    CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
        content()
    }
}

entonces simplemente usa

RightToLeftLayout {
    ViewToBeChanged()
}

o

RightToLeftLayout {
    Row {
        ...
    }
}
   



------------------------------------

Usar CompositionLocalProvider para cambiar la orientación tiene el riesgo potencial de hacer que todos los diseños secundarios cambien de orientación, lo que puede no ser lo que esperamos. Y usar LazyColumn o LazyRow puede invertir el diseño, pero la funcionalidad de los diseños secundarios será limitada y existen algunas restricciones extrañas, así que aquí está mi solución

@Composable
fun ReversibleRow(
    modifier: Modifier = Modifier,
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
    verticalAlignment: Alignment.Vertical = Alignment.Top,
    reverseLayout: Boolean = false,
    content: @Composable RowScope.() -> Unit
) {
    val originDirection = LocalLayoutDirection.current
    val direction = when {
        reverseLayout -> when (originDirection) {
            LayoutDirection.Rtl -> LayoutDirection.Ltr
            else -> LayoutDirection.Rtl
        }
        else -> originDirection
    }
    CompositionLocalProvider(LocalLayoutDirection provides direction) {
        Row(modifier, horizontalArrangement, verticalAlignment) {
            CompositionLocalProvider(LocalLayoutDirection provides originDirection) {
                content()
            }
        }
    }
}

Utilice ReversibleRow para reemplazar Row. lo mismo para la columna

1

Esta debería ser la respuesta correcta. Como se mencionó en otros comentarios, usar CompositionLocalProvider tiene el riesgo de modificar todos los elementos en el subárbol.

-Christopher Perry

13 de junio de 2023 a las 21:53

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare