簡體   English   中英

Jetpack Compose:管理共享 UI 狀態

[英]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)
        }
    }
}

因此,使用此代碼,我有以下屏幕:

屏幕A 屏幕B 屏幕C

請注意,我可以通過執行以下Actions根據當前屏幕更改TopAppBarActions

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!!!! -------------------
    }
)
  1. 我的第一個問題是這是否是正確的方法?

  2. 對於第二個問題,我覺得我在上一個屏幕中設置的值應該由當前屏幕負責。 所以我嘗試這樣做?

 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

或許這篇文章能幫到你...

https://afzaln.com/intro-to-jetpack-compose-navigation/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM