Правильно ли мое решение? Какие решения вы порекомендуете?
Я использую безопасную навигацию по составному типу. Я создал вспомогательную модель представления для navHost для хранения флага isValidated и для передачи сложных моделей из списка в элементы, например. внутри annoucementDetails (без варианта с глубокой ссылкой) Details = viewModel.getDataAndConsume(DETAILS_KEY):
Все работает нормально, но я ищу более простое решение.
@HiltViewModel
class NavHostViewModel @Inject constructor(
val sessionManager: SessionManager
) : ViewModel() {
private val dataStore = mutableMapOf()
fun setData(key: String, value: T) {
dataStore[key] = value
}
@Suppress("UNCHECKED_CAST")
fun getData(key: String): T? {
return dataStore[key] as? T
}
@Suppress("UNCHECKED_CAST")
fun getDataAndConsume(key: String): T? {
val result = dataStore[key] as? T
removeData(key)
return result
}
fun removeData(key: String) {
dataStore.remove(key)
}
}
мой NavHost:
composable(
deepLinks = listOf(
navDeepLink {
uriPattern = "myApp://announcements?id={id}"
}
)
) { backStackEntry ->
val args = backStackEntry.toRoute()
if (args.id != null) { // deeplink entry
var isDeepLinkValidated by remember { mutableStateOf(null) }
LaunchedEffect(Unit) {
val validated = viewModel.getData(IS_VALIDATED)
if (validated == true) {
viewModel.removeData(IS_VALIDATED) // consume flag
isDeepLinkValidated = true
} else {
// mark that we're redirecting to validation
viewModel.setData(IS_VALIDATED, false)
navController.navigate(Route.ValidatePin)
}
}
if (isDeepLinkValidated == true) {
AnnouncementDetailsScreen(
id = args.id,
onBack = {
navController.navigateUp()
}
)
}
} else { // announcements list entry
var details by remember { mutableStateOf(null) }
LaunchedEffect(Unit) {
details = viewModel.getDataAndConsume(DETAILS_KEY)
}
AnnouncementDetailsScreen(
announcementDetails = details,
onBack = {
navController.navigateUp()
},
)
}
}
composable {
PinBiometricValidationScreen(goNext = {
val isDeeplinkRedirect = viewModel.getData(IS_VALIDATED) == false
if (isDeeplinkRedirect) {
// Mark validation done and go back to previous destination
viewModel.setData(IS_VALIDATED, true)
val previousEntry = navController.previousBackStackEntry
val originalDestination = previousEntry?.toRoute() //
if (originalDestination?.id != null) {
navController.navigate(Route.Home) {
// This clears any previous history,
popUpTo(navController.graph.id) {
inclusive = true
}
}
navController.navigate(originalDestination)
} else {
navActions.navigateReplacingCurrent(route = Route.Home)
}
} else {
// Normal flow
navActions.navigateReplacingCurrent(route = Route.Home)
}
}, onForgotPin = {
navController.navigate(route = Route.ResetApp)
})
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... validation