Problem statement: I'm expecting that from this code I can share List data first screen to another screen.
Stacktrace
java.lang.IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/post/filter/SnapshotStateList(value=[/storage/emulated/0/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Images/IMG-20240201-WA0010.jpg, /storage/emulated/0/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Video/VID-20240210-WA0001.mp4, /storage/emulated/0/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Video/VID-20240210-WA0002.mp4, /storage/emulated/0/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Video/VID-20240210-WA0000.mp4])@57386330 } cannot be found in the navigation graph ComposeNavGraph(0x0) startDestination={Destination(0x78d845ec) route=home} at androidx.navigation.NavController.navigate(NavController.kt:1815) at androidx.navigation.NavController.navigate(NavController.kt:2221) at androidx.navigation.NavController.navigate$default(NavController.kt:2216) at com.sociallab.feature.post.createPost.PostCreateScreenKt$PostCreateScreen$1$2.invoke(PostCreateScreen.kt:95) at com.sociallab.feature.post.createPost.PostCreateScreenKt$PostCreateScreen$1$2.invoke(PostCreateScreen.kt:91) at androidx.compose.foundation.ClickableNode$clickPointerInput$3.invoke-k-4lQ0M(Clickable.kt:655)
Mainactivity.kt
@Composable
private fun MyNavigationHost(
modifier: Modifier,
navController: NavHostController,
) {
NavHost(
navController,
modifier = modifier,
startDestination = AppRoute.Home.route
) {
postNavGraph(navController)
}
}
postNavGraph.kt
fun NavGraphBuilder.postNavGraph(
navController: NavHostController,
) {
composable(PostRoute.Create.route) {
PostCreateScreen(
navController,
hiltViewModel()
)
}
composable(PostRoute.Filter.route) {
FilterPostScreen(
navController,
hiltViewModel()
)
}
}
PostRoute.kt
sealed class PostRoute(route: String, routePlaceholder: String) : AppRoute(route, routePlaceholder) {
data object Create : PostRoute("$PREFIX/create","$PREFIX/create" )
data object Filter : PostRoute("$PREFIX/filter","$PREFIX/filter")
data object Final:PostRoute("$PREFIX/final","$PREFIX/final")
data object Music:PostRoute("$PREFIX/music","$PREFIX/music")
// data class MediaList: PostRoute("$PREFIX/filter","$PREFIX/filter")
// data object MediaList(val data: List<String>) : PostRoute("$PREFIX/filter/$data","$PREFIX/filter/data")
/*data class MediaList(val data: List<String>) : PostRoute("$PREFIX/filter/{${data}}", "$PREFIX/filter/{${data}}")*/
}
ViewModel.kt
@HiltViewModel
class MediaViewModel @Inject constructor() : ViewModel() {
private val _selectedMediaList = MutableStateFlow<List<String>>(emptyList())
val selectedMediaList: StateFlow<List<String>> = _selectedMediaList
fun updateSelectedMedia(media: List<String>) {
_selectedMediaList.value = media
}
}
Screen A.kt on Next button click listner
viewModel.updateSelectedMedia(selectedMediaList)
// navController.navigate(PostRoute.MediaList(selectedMediaList).route)
navController.navigate(PostRoute.Filter.route)
Screen B.kt Fetch data
val selectedMediaList by viewModel.selectedMediaList.collectAsState()
// Update the ViewModel when selectedMediaList changes
LaunchedEffect(selectedMediaList) {
viewModel.updateSelectedMedia(selectedMediaList)
}
My only problem was to share list of string using route and this is how I solved.
And this solution of viewmodel i did my changes for solution.
Navgraph
composable(PostRoute.Create.route) {
val viewModel: FilterScreenViewModel = hiltViewModel()
PostCreateScreen(
navController,
viewModel
)
}
composable(PostRoute.MediaList(emptyList()).routePlaceholder) {
val viewModel: FilterScreenViewModel = hiltViewModel()
FilterPostScreen(
navController,
viewModel
)
}
PostRoute
data class MediaList(
val data: List<String>
) : PostRoute(
"$PREFIX/filters?references=${
URLEncoder.encode(
data.joinToString(separator = ","),
"UTF-8"
)
}",
"$PREFIX/filters?references={references}"
)
viewmodel
val data: List<String>
get() {
val joinedString = savedStateHandle.get<String>("references") ?: ""
return if (joinedString.isNotEmpty()) {
joinedString.split(",").map { it.replace("+", " ") }
} else {
listOf()
}
}
Screen B
sliderList = viewModel.data
mention viewmodel and then get data in list parameter
Screen A
navController.navigate(PostRoute.MediaList(selectedMediaList).route)