Попытка понять ViewModels и навигацию с помощью Jetpack Compose ⇐ Android
Попытка понять ViewModels и навигацию с помощью Jetpack Compose
Я пытаюсь понять, как использовать ViewModel, содержащую значения, которые можно передавать на разные экраны.
Я написал очень простую программу, чтобы попытаться понять эту концепцию.
Вот моя основная активность:
запечатанный класс Destination (val маршрут: String) { объект PlayerSelection: Destination("PlayerSelection") объект TwoPlayerGame: Destination("TwoPlayerGame") объект ThreePlayerGame: Destination("ThreePlayerGame") объект FourPlayerGame: Destination("FourPlayerGame") } класс MainActivity : ComponentActivity() { частный val viewModel: MainViewModel от viewModels() переопределить fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Viewmodels_and_NavigationTheme { // Поверхностный контейнер, использующий цвет фона из темы Поверхность( модификатор = Модификатор.fillMaxSize(), цвет = MaterialTheme.colorScheme.background ) { ScreenSetup(viewModel) } } } } } Вот мой NavigationAppHost:
@Композитный весело NavigationAppHost (navController: NavController, viewModel: MainViewModel) { NavHost(navController = navController as NavHostController, startDestination = "PlayerSelection") { composable(Destination.PlayerSelection.route) { PlayerSelection(navController,MainViewModel()) } composable(Destination.TwoPlayerGame.route) {TwoPlayerGame(navController,MainViewModel())} composable(Destination.ThreePlayerGame.route) {ThreePlayerGame(navController,MainViewModel())} composable(Destination.FourPlayerGame.route) {FourPlayerGame(navController,MainViewModel())} } }
Вот моя настройка ScreenSetup:
@OptIn(ExperimentalMaterial3Api::class) @Композитный весело ScreenSetup (viewModel: MainViewModel) { //Навигация val navController = RememberNavController() Строительные леса( topBar = { TopAppBar(title = { Text(text = "Viewmodels and Navigation") }) }, содержимое = { дополнение -> Столбец(Modifier.padding(padding)) { NavigationAppHost (navController = navController, viewModel) } }, BottomBar = { Text(text = "BottomBar") } ) }
Вот составной PlayerSelection:
@Композитный весело PlayerSelection (navController: NavController, viewModel: MainViewModel) { val HowManyPlayers: Int от viewModel.howManyPlayers.collectAsState() Столбец { Ряд { Text(text = «Сколько игроков?») } Ряд() { Кнопка(onClick = {viewModel.Selection(2) }) { Текст("Два игрока") } Button(onClick = { viewModel.Selection(3) }) { Текст("Три игрока") } Button(onClick = {viewModel.Selection(4) }) { Текст("Четыре игрока") } } Ряд() { Text(text = "Текущее значение, хранящееся в MainViewModel = ${HowManyPlayers}") } Кнопка (onClick = { если (HowManyPlayers == 2) { navController.navigate(Destination.TwoPlayerGame.route) } если (HowManyPlayers == 3) { navController.navigate(Destination.ThreePlayerGame.route) } если (HowManyPlayers == 4) { navController.navigate(Destination.FourPlayerGame.route) } }) { Text(text = «Нажмите, чтобы перейти к следующему экрану») } } }
Вот MainViewModel:
класс MainViewModel : ViewModel() { вар _howManyPlayers = MutableStateFlow(0) вар HowManyPlayers = _howManyPlayers.asStateFlow() забавный выбор (игроки: Int) { _howManyPlayers.value = игроки } }
А вот составная игра TwoPlayerGame:
@Composable весело TwoPlayerGame (navController: NavController, viewModel: MainViewModel) { val HowManyPlayers с помощью viewModel.howManyPlayers.collectAsState() Столбец { Строка(Modifier.padding(50.dp)) { Text(text = «Игра для двух игроков») } Ряд { Text(text = "Значение HowManyPlayers в viewmodel = ${howManyPlayers}") } } } Когда пользователь выбирает количество игроков на экране PlayerSelection, переменная HowManyPlayers в MainViewModel успешно изменяется в зависимости от того, какую кнопку нажимает пользователь. Я вижу, как это работает с линией:
Text(text = «Текущее значение, хранящееся в MainViewModel = ${HowManyPlayers}»)
Это очень круто. Однако когда я нажимаю кнопку, чтобы перейти к TwoPlayerGame, переменная HowManyPlayers в MainViewModel снова сбрасывается до 0. Почему значение HowManyPlayers в MainViewModel сбрасывается до 0 при переходе на новый экран? Есть ли способ передать ViewModel на разные экраны, сохраняя значения переменных внутри переданной ViewModel?
Спасибо, что рассмотрели мой вопрос, я очень ценю это!
Я пытаюсь понять, как использовать ViewModel, содержащую значения, которые можно передавать на разные экраны.
Я написал очень простую программу, чтобы попытаться понять эту концепцию.
Вот моя основная активность:
запечатанный класс Destination (val маршрут: String) { объект PlayerSelection: Destination("PlayerSelection") объект TwoPlayerGame: Destination("TwoPlayerGame") объект ThreePlayerGame: Destination("ThreePlayerGame") объект FourPlayerGame: Destination("FourPlayerGame") } класс MainActivity : ComponentActivity() { частный val viewModel: MainViewModel от viewModels() переопределить fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Viewmodels_and_NavigationTheme { // Поверхностный контейнер, использующий цвет фона из темы Поверхность( модификатор = Модификатор.fillMaxSize(), цвет = MaterialTheme.colorScheme.background ) { ScreenSetup(viewModel) } } } } } Вот мой NavigationAppHost:
@Композитный весело NavigationAppHost (navController: NavController, viewModel: MainViewModel) { NavHost(navController = navController as NavHostController, startDestination = "PlayerSelection") { composable(Destination.PlayerSelection.route) { PlayerSelection(navController,MainViewModel()) } composable(Destination.TwoPlayerGame.route) {TwoPlayerGame(navController,MainViewModel())} composable(Destination.ThreePlayerGame.route) {ThreePlayerGame(navController,MainViewModel())} composable(Destination.FourPlayerGame.route) {FourPlayerGame(navController,MainViewModel())} } }
Вот моя настройка ScreenSetup:
@OptIn(ExperimentalMaterial3Api::class) @Композитный весело ScreenSetup (viewModel: MainViewModel) { //Навигация val navController = RememberNavController() Строительные леса( topBar = { TopAppBar(title = { Text(text = "Viewmodels and Navigation") }) }, содержимое = { дополнение -> Столбец(Modifier.padding(padding)) { NavigationAppHost (navController = navController, viewModel) } }, BottomBar = { Text(text = "BottomBar") } ) }
Вот составной PlayerSelection:
@Композитный весело PlayerSelection (navController: NavController, viewModel: MainViewModel) { val HowManyPlayers: Int от viewModel.howManyPlayers.collectAsState() Столбец { Ряд { Text(text = «Сколько игроков?») } Ряд() { Кнопка(onClick = {viewModel.Selection(2) }) { Текст("Два игрока") } Button(onClick = { viewModel.Selection(3) }) { Текст("Три игрока") } Button(onClick = {viewModel.Selection(4) }) { Текст("Четыре игрока") } } Ряд() { Text(text = "Текущее значение, хранящееся в MainViewModel = ${HowManyPlayers}") } Кнопка (onClick = { если (HowManyPlayers == 2) { navController.navigate(Destination.TwoPlayerGame.route) } если (HowManyPlayers == 3) { navController.navigate(Destination.ThreePlayerGame.route) } если (HowManyPlayers == 4) { navController.navigate(Destination.FourPlayerGame.route) } }) { Text(text = «Нажмите, чтобы перейти к следующему экрану») } } }
Вот MainViewModel:
класс MainViewModel : ViewModel() { вар _howManyPlayers = MutableStateFlow(0) вар HowManyPlayers = _howManyPlayers.asStateFlow() забавный выбор (игроки: Int) { _howManyPlayers.value = игроки } }
А вот составная игра TwoPlayerGame:
@Composable весело TwoPlayerGame (navController: NavController, viewModel: MainViewModel) { val HowManyPlayers с помощью viewModel.howManyPlayers.collectAsState() Столбец { Строка(Modifier.padding(50.dp)) { Text(text = «Игра для двух игроков») } Ряд { Text(text = "Значение HowManyPlayers в viewmodel = ${howManyPlayers}") } } } Когда пользователь выбирает количество игроков на экране PlayerSelection, переменная HowManyPlayers в MainViewModel успешно изменяется в зависимости от того, какую кнопку нажимает пользователь. Я вижу, как это работает с линией:
Text(text = «Текущее значение, хранящееся в MainViewModel = ${HowManyPlayers}»)
Это очень круто. Однако когда я нажимаю кнопку, чтобы перейти к TwoPlayerGame, переменная HowManyPlayers в MainViewModel снова сбрасывается до 0. Почему значение HowManyPlayers в MainViewModel сбрасывается до 0 при переходе на новый экран? Есть ли способ передать ViewModel на разные экраны, сохраняя значения переменных внутри переданной ViewModel?
Спасибо, что рассмотрели мой вопрос, я очень ценю это!
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Различия и лучшие практики для использования ViewModels в XML против JetPack Compose
Anonymous » » в форуме Android - 0 Ответы
- 6 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Jetpack составляет ViewModels – должен ли я иметь одну ViewModel для разных вызовов API?
Anonymous » » в форуме Android - 0 Ответы
- 29 Просмотры
-
Последнее сообщение Anonymous
-