I am currently working on a migration code from Java to Kotlin with Android Jetpack Compose
The use case is a QR Code has to be generated for coordinates data sent from the 1st screen to the QR Code display screen. I have to pass coordinate data via the Navigation graph from the previous screen to the next screen. The fetched data via the navigation graph will be used to generate a QR Code to share the coordinate data with others
I did go through several documentation that passing parameters to NavHost startdestination is not possible however I do not have any other option. Since this is a project code I cannot take the liberty to change the NAvHost configured and I have to achieve the navigation only with what is available.
Since this is the actual project code I have changed the names of the methods and composables. Hence please ignore the typos. Passing parameter data to startDestination is not passing the data in the AppNAvGraph -> composable.
I pass the data like this
@AndroidEntryPoint
class QRCodeScreen(val location: Location) : BaseFragment() {
private val appViewModel: AppViewModel by viewModels()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
val locationJson = location.toJson(true)
MyApp(
viewModel = appViewModel, initialDestination = NavigationRoute.ShareQRCodeData,
initialDestinationParameters = arrayOf("locationJson" to locationJson.toString()),
)
}
}
}
}
// The Navigation graph should bring the passed parameter data to this composable.
@Composable
fun QRCodeScreen(
qrCodeScreenViewModel: QRCodeScreenViewModel,
location: Location?,
modifier: Modifier = Modifier,
) {
// location object will be used from here onwards to generate a QR Code
QRCodeScreen(
modifier = modifier,
)
}
MyApp
@Composable
fun MyApp(
viewModel: MyAppViewModel,
modifier: Modifier = Modifier,
initialDestination: NavigationRoute = NavigationRoute.Map,
vararg initialDestinationParameters: Pair<String, String?> = emptyArray(),
) {
val navigationController = rememberNavController()
var startDestination = initialDestination.route
if (initialDestinationParameters.isNotEmpty()) {
val parametersMap = initialDestinationParameters.toMap()
val queryString = parametersMap.entries.joinToString("&") {
"${it.key}=${it.value}"
}
startDestination = "${initialDestination.route}/$queryString"
navigationController.navigate(startDestination)
}
MyAppTheme {
BackHandler {
navigationController.navigateUp()
}
CompositionLocalProvider(LocalWindowSizeClass provides windowSizeClass) {
NavHost(
modifier = modifier,
navController = navigationController,
startDestination = startDestination,
enterTransition = { defaultEnterTransition },
exitTransition = { defaultExitTransition },
popEnterTransition = { defaultPopEnterTransition },
popExitTransition = { defaultPopExitTransition },
) {
AppNavGraph(navController = navigationController, appViewModel = viewModel)
}
}
}
}
NavGraph
sealed class NavigationRoute(val route: String) {
object ShareQRCodeData : NavigationRoute("ShareQRCodeData")
}
fun NavGraphBuilder.AppNavGraph(navController: NavController, appViewModel: MyAppViewModel) {
composable(
route = "${NavigationRoute.ShareQRCodeData.route}/locationJson={locationJson}",
arguments = listOf(
navArgument("locationJson") {
type = NavType.StringType
},
),
) { backStackEntry ->
// This is coming only as null or {} if I pass a default value.
val locationJson = backStackEntry.arguments?.getString("locationJson")
val location = Gson().fromJson(locationJson, RichLocation::class.java)
val viewModel = hiltViewModel<ShareDestinationViewModel>()
ShareDestinationScreen(shareDestinationViewModel = viewModel, location = location)
}
}
I did go through the methods provided in this link. https://developer.android.com/guide/navigation/use-graph/pass-data
but my project does not use any XML navigation graph and it is done programmatically. I could not apply that here.
Can any of you please show me some good ways? I am breaking my head for two days.
Edit: I am getting errors like this java.lang.IllegalArgumentException: Cannot navigate to NavDeepLinkRequest{ uri=android-app://androidx.navigation/ShareQRCodeData/locationJson={"location":{"coordinate":{"latitude":54.845,"longitude":7.20}},"title":"N 54.845° E 7.20°","description":"Coordinate","type":{"type":"coordinate"}} }. Navigation graph has not been set for NavController androidx.navigation.NavHostController@650fc28.