How to pass argument in Android Navigation using Kotlin DSL

Viewed 431

I have created my NavGraph using the Kotlin DSL and everything is fine. But I'm struggling to pass a simple argument between destinations.

I'm folowing this Android Docs without success: https://developer.android.com/guide/navigation/navigation-kotlin-dsl#constants

Part of graph that adds the argument as the docs says:

            fragment<RestaurantsTabsFragment>(
                "${CampusSelectorDestinations.restaurantsTabsFragment}/" +
                        CampusSelectorArguments.campusId
            ) {
                argument(CampusSelectorArguments.campusId) {
                    type = NavType.StringType
                    defaultValue = "test"
                }
            }

Code with the navigation action trying to pass a argument:

        campusesAdapter.onCampusClick = { campusId ->
                 findNavController().navigate("${CampusSelectorDestinations.restaurantsTabsFragment}/" + campusId
        }

Error I get:

IllegalArgumentException: Navigation destination that matches request NavDeepLinkRequest{ uri=android-app://androidx.navigation/restaurantsTabsFragment/jCkuLbzRHtW0CUzDFWYw } cannot be found in the navigation graph NavGraph

Can anyone help me? I can provide more information if needed

2 Answers

The pattern to pass the argumet route is wrong at the docs:

enter image description here

For luck, I've found this explanation inside a Navigation Lib class and that solved my problem (after 2 days struggling):

... In addition to a direct Uri match, the following features are supported: Uris without a scheme are assumed as http and https. For example, www.example.com will match http://www.example.com and https://www.example.com. Placeholders in the form of {placeholder_name} matches 1 or more characters. The String value of the placeholder will be available in the arguments Bundle with a key of the same name. For example, http://www.example.com/users/{id} will match http://www.example.com/users/4. The .* wildcard can be used to match 0 or more characters. These Uris can be declared in your navigation XML files by adding one or more elements as a child to your destination. ...

Hope someone from Google see this and fixes the docs. (or explain if I'm wrong)

Just put your arguments into curved breaks and separate them by slash as it shown in the example below.

  1. Define your destination with all required argument:

    fragment<TransactionFragment>("${MainNavRoute.transaction}/{arg1}/{arg2}") {
       argument("arg1") {
           type = NavType.StringType
       }
       argument("arg2") {
           type = NavType.LongType
       }
    
  2. Navigation to the destination:

    findNavController().navigate("${MainNavRoute.transaction}/string_value/2")

Also, I have reported an issue to the tracker too. https://issuetracker.google.com/issues/221895357

Related