-
-
Notifications
You must be signed in to change notification settings - Fork 776
Open
Description
Describe the bug
I have two compose function : SendGiftScreen and SelectUserScreen
I navigate from SendGiftScreen to SelectUserScreen and i want to get the value in SendGiftScreenViewModel by savedStateHandle, but i can't get the value
how i should do?
To Reproduce
Koin module and version:
koinVersion = "4.1.1"
navigationCompose = "2.9.5"
koin-android = { module = "io.insert-koin:koin-android", version.ref = "koinVersion"}
koin-compose = { module = "io.insert-koin:koin-androidx-compose", version.ref = "koinVersion"}
koin-compose-navigation = { module = "io.insert-koin:koin-androidx-compose-navigation", version.ref = "koinVersion"}
koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koinVersion"}
navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
Snippet or Sample project to help reproduce
- The viewmodel inject
viewModel { SendGiftScreenViewModel(get()) }
viewModel { SelectUserScreenViewModel() }
- SelectUserScreen:
@Composable
fun SelectUserScreen(
viewmodel : SelectUserScreenViewModel = koinViewModel()
) {
val uiState by viewmodel.uiState.collectAsStateWithLifecycle()
val context = LocalContext.current
val appNavigator = LocalAppNavigator.current
LaunchedEffect(Unit) {
viewmodel.uiActionState.collect {
when(it) {
is SelectUserScreenEffect.ReturnSelectUser -> {
val navController = appNavigator.provideNavController()
val previousEntry = navController.previousBackStackEntry
previousEntry?.savedStateHandle?.set("selected_user", it.userInfo)
appNavigator.navigateBack()
}
is SelectUserScreenEffect.ShowToast -> {
Toast.makeText(context, it.message, Toast.LENGTH_SHORT).show()
}
}
}
}
SelectUserContent(
uiState = uiState,
onEvent = viewmodel::onEvent
)
}- SendGiftScreenViewModel: can't get the value in ViewModel
class SendGiftScreenViewModel(
private val savedStateHandle: SavedStateHandle
) : BaseActionStateViewModel<SendGiftScreenUIState, SendGiftScreenUIEvent, SendGiftScreenEffect>(),
KoinComponent {
private val wishRepository: XXXRepository by inject()
init {
// This can't get the value from SavedStateHandle when SelectUserScreen back
viewModelScope.launch {
savedStateHandle.getStateFlow<SimpleUser?>("selected_user", null)
.filterNotNull()
.collect { user ->
setState { copy(targetUser = user) }
savedStateHandle.remove<SimpleUser?>("selected_user")
}
}
}
}
- SendGiftScreen : this can get this value
@Composable
fun SendGiftScreen(
viewmodel: SendGiftScreenViewModel = koinViewModel()
) {
val uiState by viewmodel.uiState.collectAsStateWithLifecycle()
val appNavigator = LocalAppNavigator.current
LaunchedEffect(Unit) {
val navController = appNavigator.provideNavController()
val savedStateHandle = navController.currentBackStackEntry?.savedStateHandle
// this can get the value
savedStateHandle?.getStateFlow<SimpleUser?>("selected_user", null)
?.collect { user ->
if (user != null) {
// Update ViewModel state
viewmodel.onEvent(SendGiftScreenUIEvent.OnUserSelected(user))
// Clear the result
savedStateHandle.remove<SimpleUser?>("selected_user")
}
}
}- AppNavigator:
class AppNavigatorImpl(
private val navController: NavController
) : AppNavigator {
override fun navigateTo(
screen: Screen,
popUpTo: Screen?,
inclusive: Boolean,
singleTop: Boolean,
restoreState: Boolean,
saveState: Boolean
) {
navController.navigate(screen) {
launchSingleTop = singleTop
if (restoreState) this.restoreState = true
popUpTo?.let {
popUpTo(it) {
this.inclusive = inclusive
if (saveState) this.saveState = true
}
}
}
}
override fun navigateBack() : Boolean{
return navController.popBackStack()
}
override fun navigateToWithPopAll(screen: Screen) {
navController.navigate(screen) {
popUpTo(navController.graph.findStartDestination().id) {
inclusive = true
}
launchSingleTop = true
}
}
override fun provideNavController(): NavController {
return navController
}
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels