【发布时间】:2021-02-21 12:12:02
【问题描述】:
Jetpack Compose 中是否有任何 Orientation 助手类,比如 Flutter 有 https://flutter.dev/docs/cookbook/design/orientation ? 我需要知道何时更改了方向以正确调整我的布局。
【问题讨论】:
标签: android android-jetpack-compose
Jetpack Compose 中是否有任何 Orientation 助手类,比如 Flutter 有 https://flutter.dev/docs/cookbook/design/orientation ? 我需要知道何时更改了方向以正确调整我的布局。
【问题讨论】:
标签: android android-jetpack-compose
我们可以使用LocalConfiguration 来监听方向变化
@Composable
fun ConfigChangeExample() {
val configuration = LocalConfiguration.current
when (configuration.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> {
Text("Landscape")
}
else -> {
Text("Portrait")
}
}
}
注意:这将无助于监听配置变化,这只会帮助获取当前配置。
【讨论】:
要观察方向,我们可以创建一个快照流来观察方向的变化,该变化会输入一个您可以直接使用的状态变量。
var orientation by remember { mutableStateOf(Configuration.ORIENTATION_PORTRAIT) }
val configuration = LocalConfiguration.current
// If our configuration changes then this will launch a new coroutine scope for it
LaunchedEffect(configuration) {
// Save any changes to the orientation value on the configuration object
snapshotFlow { configuration.orientation }
.collect { orientation = it }
}
when (orientation) {
Configuration.ORIENTATION_LANDSCAPE -> {
LandscapeContent()
}
else -> {
PortraitContent()
}
}
【讨论】:
我们可以在 jectpack compose 中使用state,这样当状态改变时,composable 会重新组合自己。
使用state收听configuration change的例子如下:-
@Composable
fun ShowConfig(config: String) {
Text(text = "$config!")
}
保持config state 处于活动状态:-
var state by mutableStateOf("Potrait")
然后监听 Activity 中的配置更改,配置时只需通过以下值更新状态:-
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
state = "Landscape" // this will automatically change the text to landscape
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
state = "Potrait" // this will automatically change the text to potrait
}
}
每当配置字符串的状态发生变化时,Greeting 可组合项都会观察配置字符串的状态。
【讨论】:
您可以从BoxWithConstraints 获取它并将width 与height 进行比较。
简单示例:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ShowScreenOrientation()
}
}
@Composable
fun ShowScreenOrientation() {
BoxWithConstraints {
val mode = remember { mutableStateOf("") }
mode.value = if (maxWidth < maxHeight) "Portrait" else "Landscape"
Text(text = "Now it is in ${mode.value} mode")
}
}
}
【讨论】:
这里有一个小帮手,用于在切换到纵向模式时将撰写行转换为列。您可能需要根据自己的目的对其进行一些调整。
@Composable
fun OrientationSwapper(
content1: @Composable (modifier: Modifier) -> Unit,
content2: @Composable (modifier: Modifier) -> Unit
) {
val portrait = LocalConfiguration.current.orientation == Configuration.ORIENTATION_PORTRAIT
if (portrait) {
Column(verticalArrangement = Arrangement.SpaceEvenly, modifier = Modifier.fillMaxSize()) {
content1(modifier = Modifier.weight(1f))
content2(modifier = Modifier.weight(1f))
}
} else {
Row(horizontalArrangement = Arrangement.SpaceEvenly, modifier = Modifier.fillMaxSize()) {
content1(modifier = Modifier.weight(1f))
content2(modifier = Modifier.weight(1f))
}
}
}
并用作:
OrientationSwapper(
content1 = { modifier ->
Text("foo", modifier = modifier) },
content2 = { modifier ->
Text("bar", modifier = modifier) })
【讨论】: