[英]Jetpack Compose: Managing Shared UI State
typealias Actions = @Composable () -> Unit
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
SampleAppTheme {
var currentScreen by remember { mutableStateOf(Screen.A) }
var title by remember { mutableStateOf("Screen A") }
var action by remember { mutableStateOf<Actions>({}) }
Scaffold(
topBar = {
TopAppBar(
title = {
Text(title)
},
actions = {
action()
}
)
}
) {
Crossfade(current = currentScreen) { screen ->
when (screen) {
Screen.A -> {
MyScreen(
name = "A",
buttonName = "to Screen B",
onNext = {
currentScreen = Screen.B
title = "Screen B"
action = {
IconButton(onClick = {}) {
Icon(asset = Icons.Sharp.Home)
}
}
}
)
}
Screen.B -> {
MyScreen(
name = "B",
buttonName = "to Screen C",
onNext = {
currentScreen = Screen.C
title = "Screen B"
action = {
IconButton(onClick = {}) {
Icon(asset = Icons.Sharp.Close)
}
}
}
)
}
Screen.C -> {
MyScreen(
name = "C",
buttonName = "to Screen A",
onNext = {
currentScreen = Screen.A
title = "Screen A"
action = {}
}
)
}
}
}
}
}
}
}
}
enum class Screen {
A, B, C
}
@Composable
fun MyScreen(
name: String,
buttonName: String,
onNext: () -> Unit,
) {
Column(
Modifier.fillMaxSize().padding(24.dp),
) {
Text(
modifier = Modifier.weight(1f),
text = "I am in screen $name!",
textAlign = TextAlign.Center,
style = MaterialTheme.typography.h3
)
Button(
modifier = Modifier.fillMaxWidth(),
onClick = onNext
) {
Text(text = buttonName)
}
}
}
因此,使用此代碼,我有以下屏幕:
請注意,我可以通過執行以下Actions
根據當前屏幕更改TopAppBar
的Actions
:
MyScreen(
name = "B",
buttonName = "to Screen C",
onNext = {
currentScreen = Screen.C
title = "Screen B"
// This right here!!!! -------------------
action = {
IconButton(onClick = {}) {
Icon(asset = Icons.Sharp.Close)
}
}
// This right here!!!! -------------------
}
)
我的第一個問題是這是否是正確的方法?
對於第二個問題,我覺得我在上一個屏幕中設置的值應該由當前屏幕負責。 所以我嘗試這樣做?
Screen.B -> { // This right here!!!! ------------------- onActive { title = "Screen B" action = { IconButton(onClick = {}) { Icon(asset = Icons.Sharp.Home) } } } // This right here!!!! ------------------- MyScreen( name = "B", buttonName = "to Screen C", onNext = { currentScreen = Screen.C } ) }
所以現在,設置狀態的責任是在當前屏幕上,而不是像以前一樣在它之前的屏幕上。
這是否更好?
經過一些測試:顯然從屏幕 A -> 屏幕 B -> 屏幕 C 移動使得onActive { }
被稱為錯誤的順序。 所以在某些狀態下,屏幕 B 將屏幕 A 作為其標題...屏幕 C 將屏幕 B 作為其標題,依此類推...
只是要意識到即使第一種方法也有缺陷,因為您還必須在返回屏幕時設置狀態..讓我們說在做...屏幕 A -> 屏幕 B -> 屏幕 C -> 按回(屏幕 B)。 ..現在狀態不對...
我想這個問題可以使用 Jetpack Navigation for Compose 來解決。
https://developer.android.com/jetpack/compose/navigation
或許這篇文章能幫到你...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.