Жизненный цикл ViewModel, инъецированной в корневой композицииAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Жизненный цикл ViewModel, инъецированной в корневой композиции

Сообщение 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())
}
}


Подробнее здесь: https://stackoverflow.com/questions/796 ... composable
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»