Я сталкиваюсь с странным поведением в своем приложении, и, вероятно, это из -за жизненного цикла ViewModel (вводится в корневой композиции), но я не могу найти какую -либо информацию о нем в документации. В. Composable, которая обрабатывает навигацию, вводит ViewModels к данным экранам и пассусным состояниям, на экранах наносит inaction. LoginViewModel не была не очищена, он/сам экран обрабатывает навигацию по домашнему экрану. повторно, но я не знаю, является ли это правильным подходом.@OptIn(
ExperimentalMaterial3Api::class,
ExperimentalMaterial3ExpressiveApi::class,
ExperimentalMaterial3AdaptiveApi::class
)
@Composable
fun NavigationRoot(startDestination: NavKey = Onboarding) {
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
ObserveAsEvents(flow = SnackbarController.events, snackbarHostState) { event ->
scope.launch {
snackbarHostState.currentSnackbarData?.dismiss()
val result = snackbarHostState.showSnackbar(
message = event.message,
actionLabel = event.action?.name,
duration = when (event.duration) {
Duration.SHORT -> SnackbarDuration.Short
Duration.LONG -> SnackbarDuration.Long
Duration.INDEFINITE -> SnackbarDuration.Indefinite
}
)
if (result == SnackbarResult.ActionPerformed) {
event.action?.action?.invoke()
}
}
}
val backStack = rememberNavBackStack(startDestination)
val listDetailStrategy = rememberListDetailSceneStrategy()
LaunchedEffect(startDestination) {
if (backStack.firstOrNull() != startDestination) {
backStack.clear()
backStack.add(startDestination)
}
}
@Composable
fun AppScaffold(modifier: Modifier = Modifier) {
Scaffold(
modifier = modifier
.fillMaxSize(),
contentWindowInsets = WindowInsets(0, 0, 0, 0),
snackbarHost = { SnackbarHost(snackbarHostState) },
content = { contentPadding ->
NavDisplay(
modifier = Modifier
.padding(contentPadding)
.consumeWindowInsets(contentPadding),
backStack = backStack,
onBack = { keysToRemove ->
repeat(keysToRemove) { backStack.removeLastOrNull() }
},
entryProvider = entryProvider {
entry {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
OnboardingScreen(
stateProvider = { state },
onAction = viewModel::onAction,
uiEvent = viewModel.uiEvent,
onNavigate = { dest ->
backStack.apply {
if (dest is ServerList) clear()
add(dest)
}
}
)
}
entry {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
LoginScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
onNavigate = { dest ->
backStack.clear()
backStack.add(dest)
}
)
}
entry {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
RegisterScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
onNavigate = { dest ->
backStack.clear()
backStack.add(dest)
}
)
}
entry(metadata = ListDetailSceneStrategy.listPane()) {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
val paging = viewModel.paging.collectAsLazyPagingItems()
ServerScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
pagedList = paging,
onNavigate = { dest ->
if (dest is ServerDetails && backStack.lastOrNull() is ServerDetails) {
backStack[backStack.lastIndex] = dest
} else backStack.add(dest)
}
)
}
entry(metadata = ListDetailSceneStrategy.detailPane()) { key ->
val viewModel: ServerDetailsViewModel = koinViewModel(
key = key.id.toString()
) { parametersOf(key.id, key.name) }
val state = viewModel.state.collectAsStateWithLifecycle()
ServerDetailsScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
onNavigate = { dest -> backStack.add(dest) }
)
}
entry {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
SettingsScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
onNavigate = { dest ->
if (dest is Onboarding) {
backStack.clear()
}
backStack.add(dest)
}
)
}
entry {
ChangePasswordScreen(onNavigateUp = { backStack.removeLastOrNull() })
}
entry {
PrivacyPolicyScreen(
url = Constants.PRIVACY_POLICY_URL,
onNavigateUp = { backStack.removeLastOrNull() }
)
}
},
sceneStrategy = listDetailStrategy
)
}
)
}
val current = backStack.lastOrNull()
val showNav = current is ServerList || current is ServerDetails || current is Settings
if (showNav) {
NavigationSuiteScaffold(
modifier = Modifier
.navigationBarsPadding(),
navigationItems = {
NavigationSuiteItem(
selected = current is ServerList || current is ServerDetails,
onClick = {
if (backStack.lastOrNull() !is ServerList) {
while (backStack.lastOrNull() !is ServerList && backStack.isNotEmpty()) {
backStack.removeLastOrNull()
}
}
},
icon = { Icon(Icons.AutoMirrored.Filled.List, contentDescription = "Servers") },
label = { Text("Servers") }
)
NavigationSuiteItem(
selected = current is Settings,
onClick = {
if (backStack.lastOrNull() !is Settings) {
backStack.add(Settings)
}
},
icon = { Icon(Icons.Default.Settings, contentDescription = "Settings") },
label = { Text("Settings") }
)
},
content = {
AppScaffold()
}
)
} else {
AppScaffold(modifier = Modifier.navigationBarsPadding())
}
}
Подробнее здесь: https://stackoverflow.com/questions/796 ... composable
Жизненный цикл ViewModel, инъецированной в корневой композиции ⇐ Android
Форум для тех, кто программирует под Android
-
Anonymous
1751189128
Anonymous
Я сталкиваюсь с странным поведением в своем приложении, и, вероятно, это из -за жизненного цикла ViewModel (вводится в корневой композиции), но я не могу найти какую -либо информацию о нем в документации. В. Composable, которая обрабатывает навигацию, вводит ViewModels к данным экранам и пассусным состояниям, на экранах наносит inaction. LoginViewModel не была не очищена, он/сам экран обрабатывает навигацию по домашнему экрану. повторно, но я не знаю, является ли это правильным подходом.@OptIn(
ExperimentalMaterial3Api::class,
ExperimentalMaterial3ExpressiveApi::class,
ExperimentalMaterial3AdaptiveApi::class
)
@Composable
fun NavigationRoot(startDestination: NavKey = Onboarding) {
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
ObserveAsEvents(flow = SnackbarController.events, snackbarHostState) { event ->
scope.launch {
snackbarHostState.currentSnackbarData?.dismiss()
val result = snackbarHostState.showSnackbar(
message = event.message,
actionLabel = event.action?.name,
duration = when (event.duration) {
Duration.SHORT -> SnackbarDuration.Short
Duration.LONG -> SnackbarDuration.Long
Duration.INDEFINITE -> SnackbarDuration.Indefinite
}
)
if (result == SnackbarResult.ActionPerformed) {
event.action?.action?.invoke()
}
}
}
val backStack = rememberNavBackStack(startDestination)
val listDetailStrategy = rememberListDetailSceneStrategy()
LaunchedEffect(startDestination) {
if (backStack.firstOrNull() != startDestination) {
backStack.clear()
backStack.add(startDestination)
}
}
@Composable
fun AppScaffold(modifier: Modifier = Modifier) {
Scaffold(
modifier = modifier
.fillMaxSize(),
contentWindowInsets = WindowInsets(0, 0, 0, 0),
snackbarHost = { SnackbarHost(snackbarHostState) },
content = { contentPadding ->
NavDisplay(
modifier = Modifier
.padding(contentPadding)
.consumeWindowInsets(contentPadding),
backStack = backStack,
onBack = { keysToRemove ->
repeat(keysToRemove) { backStack.removeLastOrNull() }
},
entryProvider = entryProvider {
entry {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
OnboardingScreen(
stateProvider = { state },
onAction = viewModel::onAction,
uiEvent = viewModel.uiEvent,
onNavigate = { dest ->
backStack.apply {
if (dest is ServerList) clear()
add(dest)
}
}
)
}
entry {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
LoginScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
onNavigate = { dest ->
backStack.clear()
backStack.add(dest)
}
)
}
entry {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
RegisterScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
onNavigate = { dest ->
backStack.clear()
backStack.add(dest)
}
)
}
entry(metadata = ListDetailSceneStrategy.listPane()) {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
val paging = viewModel.paging.collectAsLazyPagingItems()
ServerScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
pagedList = paging,
onNavigate = { dest ->
if (dest is ServerDetails && backStack.lastOrNull() is ServerDetails) {
backStack[backStack.lastIndex] = dest
} else backStack.add(dest)
}
)
}
entry(metadata = ListDetailSceneStrategy.detailPane()) { key ->
val viewModel: ServerDetailsViewModel = koinViewModel(
key = key.id.toString()
) { parametersOf(key.id, key.name) }
val state = viewModel.state.collectAsStateWithLifecycle()
ServerDetailsScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
onNavigate = { dest -> backStack.add(dest) }
)
}
entry {
val viewModel = koinViewModel()
val state = viewModel.state.collectAsStateWithLifecycle()
SettingsScreen(
stateProvider = { state },
uiEvent = viewModel.uiEvent,
onAction = viewModel::onAction,
onNavigate = { dest ->
if (dest is Onboarding) {
backStack.clear()
}
backStack.add(dest)
}
)
}
entry {
ChangePasswordScreen(onNavigateUp = { backStack.removeLastOrNull() })
}
entry {
PrivacyPolicyScreen(
url = Constants.PRIVACY_POLICY_URL,
onNavigateUp = { backStack.removeLastOrNull() }
)
}
},
sceneStrategy = listDetailStrategy
)
}
)
}
val current = backStack.lastOrNull()
val showNav = current is ServerList || current is ServerDetails || current is Settings
if (showNav) {
NavigationSuiteScaffold(
modifier = Modifier
.navigationBarsPadding(),
navigationItems = {
NavigationSuiteItem(
selected = current is ServerList || current is ServerDetails,
onClick = {
if (backStack.lastOrNull() !is ServerList) {
while (backStack.lastOrNull() !is ServerList && backStack.isNotEmpty()) {
backStack.removeLastOrNull()
}
}
},
icon = { Icon(Icons.AutoMirrored.Filled.List, contentDescription = "Servers") },
label = { Text("Servers") }
)
NavigationSuiteItem(
selected = current is Settings,
onClick = {
if (backStack.lastOrNull() !is Settings) {
backStack.add(Settings)
}
},
icon = { Icon(Icons.Default.Settings, contentDescription = "Settings") },
label = { Text("Settings") }
)
},
content = {
AppScaffold()
}
)
} else {
AppScaffold(modifier = Modifier.navigationBarsPadding())
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79683212/lifecycle-of-viewmodel-injected-in-root-composable[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия