1

I have multiple navigation graphs for multiple activities but I always have problem with navigating to fragments by navController. It always return such errors cannot be found from the current destination Destination

java.lang.IllegalArgumentException: Navigation action/destination com.my.app:id/action_orderDetailFragment_to_driverMapFragment cannot be found from the current destination Destination(com.my.app:id/driverMapFragment) label=fragment_driver_map class=com.my.app.orders.DriverMapFragment

I've tried various amount of solutions from safeargs by using Directions also navigate by ids etc. they all end up with same error. It becomes frustrating to deal with navigations

navigation screenshot

one

Fragment

class OrderDetailFragment : Fragment(), View.OnClickListener {

    lateinit var navController: NavController
    lateinit var drivermap: Button

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        navController = Navigation.findNavController(view)
        view.findViewById<Button>(R.id.drivermap).setOnClickListener(this)
    }
    
    // other functions....

    // here suppose to redirect to "driverMapFragment" from "orderDetailFragment" along with "Order ID"
    override fun onClick(v: View?) {
        when(v!!.id) {
            R.id.drivermap -> {
                // (1) Returning Error
                val bundle = bundleOf("orderIDArgument" to orderIDArgument)
                navController!!.navigate(R.id.action_orderDetailFragment_to_driverMapFragment, bundle)

                // (2) Returning Error
                // val action = OrderDetailFragmentDirections.actionOrderDetailFragmentToDriverMapFragment(bundle)
                // v.findNavController().navigate(action)
            }
        }
    }
}

PS: To avoid unnecessary comments I have to mention that I do have safeargs in gradles.

app level gradle

apply plugin: "androidx.navigation.safeargs.kotlin"

project level gradle

dependencies {
  classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
}

Update 1

two

Update 2

Structure

  1. I have OrdersFragment where list of all orders are showing to user
  2. As I was facing very same issue about getting details fragment from that list items what I did was creating new activity named it OrdersActivity in this activity I get order details by OrderDetailFragment (main fragment of the activity)
  3. Now OrdersActivity has new fragment which I'm trying to show map of order (redirecting from OrderDetailFragment to driverMapFragment)

PS: I am aware that this structure is a bit messed up (mostly because I was forced to make OrdersActivity which I didn't want to, but same issue (error) made me to do it this way.

Now here is my activity_orders.xml

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="56dp"
    android:fillViewport="true"
    tools:context=".orders.OrdersActivity">

        // by default it loads `OrderDetailFragment` then its supposed to switch to maps fragment when button is clicked inside `OrderDetailFragment`    
        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/orderFragmentId"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/order_detail" />
</ScrollView>

OrdersActivity.kt

class OrdersActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_orders)

        // make sure main fragment loads only once
        if (savedInstanceState == null) {
            supportFragmentManager
                .beginTransaction()
                .add(R.id.orderFragmentId, OrderDetailFragment())
                .commit()
        }
    }

    private fun navigateTo(fragment: Fragment) {
        val transaction = supportFragmentManager
            .beginTransaction()
            .replace(R.id.orderFragmentId, fragment)
        transaction.commit()
    }
}
mafortis
  • 6,750
  • 23
  • 130
  • 288

3 Answers3

1

You are using NavHostFragment, you should not be using any FragmentTransaction at all - you're adding a second instance of your OrderDetailFragment that is outside of the NavHostFragment.

Remove all of that code from your OrdersActivity:

class OrdersActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_orders)
    }
}
ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
0

You need to move the <action outside of the <fragment, it should be a child of <navigation tag.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • Are you sure?? because that action is added by editor (i didn't type it) I drag arrow from fragment A to B and that's where android studio added it. – mafortis Apr 15 '21 at 02:20
  • This is never the correct solution as it will cause two DriverMapFragments to be added to your back stack (the error is saying you've already navigated to the DriverMapFragment). – ianhanniballake Apr 15 '21 at 02:23
  • please see my update, somehow you're correct i guess – mafortis Apr 15 '21 at 02:26
0

I put <argument> element as child of <fragment> and not as child of <action>. Immediately I got to use ClassNameArgs by navArgs().

<fragment
    android:id="@+id/SecondFragment"
    android:name="com.example.easybrowsing.SecondFragment"
    android:label="@string/second_fragment_label"
    tools:layout="@layout/fragment_second">

    <action
        android:id="@+id/action_SecondFragment_to_FirstFragment"
        app:destination="@id/FirstFragment" />
    <argument
        android:name="website"
        app:argType="com.example.easybrowsing.Website" />
</fragment>
soggypants
  • 311
  • 2
  • 5