Home > front end >  Jetpack compose deeplink handling branch.io
Jetpack compose deeplink handling branch.io

Time:04-29

I'm using branch.io for handling deep links. Deep links can contain custom metadata in a form of JsonObject. The data can be obtained by setting up a listener, inside MainActivity#onStart() which is triggered when a link is clicked.

   override fun onStart() {
    super.onStart()
    Branch
        .sessionBuilder(this)
        .withCallback { referringParams, error ->
            if (error == null) {
                val eventId = referringParams?.getString("id")
                    
                //Here I would like to navigate user to event screen
            } else {
                Timber.e(error.message)
            }
        }
        .withData(this.intent?.data).init()
}

When I retrieve eventId from referringParams I have to navigate the user to the specific event. When I was using Navigation components with fragments I could just do:

findNavController(R.id.navHost).navigate("path to event screen")

But with compose is different because I can't use navController outside of Composable since its located in MainActivity#onCreate()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        
        //I cant access navController outside of composable function
        val navController = rememberNavController()

        NavHost(
            navController = navController,
            startDestination = "HomeScreen",
        ) {
            
        }
    }
}

My question is, how can I navigate the user to a specific screen from MainActivity#onStart() when using jetpack compose navigation

CodePudding user response:

rememberNavController has pretty simple implementation: it creates NavHostController with two navigators, needed by Compose, and makes sure it's restored on configuration change.

Here's how you can do the same in your activity, outside of composable scope:

private lateinit var navController: NavHostController
private val navControllerBundleKey = "navControllerBundleKey"

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    navController = NavHostController(this).apply {
        navigatorProvider.addNavigator(ComposeNavigator())
        navigatorProvider.addNavigator(DialogNavigator())
    }

    savedInstanceState
        ?.getBundle(navControllerBundleKey)
        ?.apply(navController::restoreState)

    setContent {
        // pass navController to NavHost
    }
}

override fun onSaveInstanceState(outState: Bundle) {
    outState.putBundle(navControllerBundleKey, navController.saveState())
    super.onSaveInstanceState(outState)
}
  • Related