Reputation: 19240
I want to set a direction of a specific composable to be RTL
@Composable
fun ViewToBeChanged() {
Row {
Image()
Column {
Text("Title")
Text("Subtitle")
}
}
}
Is it possible?
Jetpack compose Layout documentation mentions LocalLayoutDirection
Change the layout direction of a composable by changing the
LocalLayoutDirection
compositionLocal.
But I have no idea how to use it in a composable to take effect.
Upvotes: 44
Views: 17678
Reputation: 207
if you need to change all activity direction, you can wrap your surface component by:
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl){
Surface(color = MaterialTheme.colorScheme.background) {
}
}
Upvotes: 1
Reputation: 71
Using CompositionLocalProvider to change orientation has the potential risk of causing all child layouts to change orientation, which may not be what we expect. And using LazyColumn or LazyRow can invert the layout but the functionality of the child layouts will be limited and there are some strange restrictions, so here is my solution
@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()
}
}
}
}
Use ReversibleRow to replace Row. same for Column
Upvotes: 7
Reputation: 5534
For a Row
specifically, you can influence the RTL / LTR behavior using the horizontalArrangement
parameter. The default is Arrangement.Start
which takes into account layout direction. Using one of Arrangement.Absolute
allows you to give an arrangement that ignores layout direction.
In your example:
@Composable
fun ViewToBeChanged() {
Row(horizontalArrangement = Arrangement.Right) {
Image()
Column {
Text("Title")
Text("Subtitle")
}
}
}
Upvotes: 4
Reputation: 2875
As a generalisation of the other answers, if this is needed in different Composables we can define the following
@Composable
fun RightToLeftLayout(content: @Composable () -> Unit) {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
content()
}
}
then simply use
RightToLeftLayout {
ViewToBeChanged()
}
or
RightToLeftLayout {
Row {
...
}
}
Upvotes: 5
Reputation: 364005
You can use the CompositionLocalProvider
to provide a custom LocalLayoutDirection
.
Something like:
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl ) {
Column(Modifier.fillMaxWidth()) {
Text("Title")
Text("Subtitle")
}
}
Upvotes: 77
Reputation: 1006924
Since I did not have your image, I tweaked your composable to:
@Composable
fun ViewToBeChanged() {
Row {
Text("Foo", modifier = Modifier.padding(end = 8.dp))
Column {
Text("Title")
Text("Subtitle")
}
}
}
That gives us:
One way to switch to RTL is to use CompositionLocalProvider
and LocalLayoutDirection
:
@Composable
fun RtlView() {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
Row {
Text("Foo", modifier = Modifier.padding(end = 8.dp))
Column {
Text("Title")
Text("Subtitle")
}
}
}
}
Here, we are saying that we are overriding the CompositionLocal
for layout direction for the contents of the trailing lambda supplied to CompositionLocalProvider()
. This gives us:
This changes the layout direction used by this branch of the composable tree, for the composables itself. English is still a LTR language, so the text is unaffected.
Upvotes: 17