Jetpack compose:更改可组合的布局方向

Mah*_*alv 6 android android-jetpack-compose

我想将特定可组合的方向设置为RTL


@Composable
fun ViewToBeChanged() {
  Row {
     Image()
     Column {
        Text("Title")
        Text("Subtitle")
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

是否可以?

Jetpack compose Layout 文档提到LocalLayoutDirection

通过更改LocalLayoutDirectioncompositionLocal来更改可组合的布局方向。

但是我不知道如何在可组合中使用它才能生效。

Gab*_*tti 7

您可以使用CompositionLocalProvider来提供自定义LocalLayoutDirection.

就像是:

CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl ) {
    Column(Modifier.fillMaxWidth()) {
        Text("Title")
        Text("Subtitle")
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

使用 CompositionLocalProvider 改变方向有导致所有子布局改变方向的潜在风险,这可能不是我们所期望的。使用 LazyColumn 或 LazyRow 可以反转布局,但子布局的功能会受到限制,并且存在一些奇怪的限制,所以这是我的解决方案

@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()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用 ReversibleRow 替换 Row。与列相同


Com*_*are 5

由于我没有您的图像,因此我将您的可组合调整为:

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

    Column {
      Text("Title")
      Text("Subtitle")
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这给了我们:

ViewToBeChanged() 渲染

切换到 RTL 的一种方法是使用CompositionLocalProviderLocalLayoutDirection

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

      Column {
        Text("Title")
        Text("Subtitle")
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们说我们正在覆盖CompositionLocal提供给 的尾随 lambda 内容的for 布局方向CompositionLocalProvider()。这给了我们:

RtlView() 渲染

这将更改可组合树的此分支使用的布局方向,用于可组合本身。英语仍然是 LTR 语言,因此文本不受影响。


Sup*_*try 5

作为其他答案的概括,如果不同的可组合项需要这样做,我们可以定义以下内容

@Composable
fun RightToLeftLayout(content: @Composable () -> Unit) {
    CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
        content()
    }
}
Run Code Online (Sandbox Code Playgroud)

然后简单地使用

RightToLeftLayout {
    ViewToBeChanged()
}
Run Code Online (Sandbox Code Playgroud)

或者

RightToLeftLayout {
    Row {
        ...
    }
}
   
Run Code Online (Sandbox Code Playgroud)