Skip to content

Navigation

It is recommended now to implement Single Activity through Navigation Component. To support this, presentation module support navigation natively. You don't have to add jetpack navigation component in your gradle configuration, this module will add it automatically for you.

The Activity

Let's say we have MainActivity that will be hosting all of our Fragment backstack, with layout like this:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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" 
    tools:context=".presentation.MainActivity">

    <androidx.fragment.app.FragmentContainerView 
        android:id="@+id/fcvDefault"
        android:name="androidx.navigation.fragment.NavHostFragment" 
        android:layout_width="0dp"
        android:layout_height="0dp" 
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent" 
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" 
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_main" />

</androidx.constraintlayout.widget.ConstraintLayout>

Keep in mind that that we have FragmentContainerView with its' Id fcvDefault. To setup the Activity with navigation Component, call the Id inside the constructor like this:

MainActivity.kt
class MainActivity : DevActivity<ActivityMainBinding>(R.id.fcvDefault)

And from that, you can follow here to start development with Navigation Component like making destination and such.

The Fragment

Opening another Fragment

Opening another Fragment with Navigation Component is easier using DevFragment. We have abstraction to search NavController so you don't have to call findNavController() every time you want to open another Fragment.

SampleFragment.kt
// Without DevFragment
findNavController().navigate(R.id.sample_action)


// With DevFragment
navigate(R.id.sample_action)

// With bundle
navigate(resId = R.id.sample_action, args = Bundle().apply {

})

Another thing is, to reduce duplicate Fragment for destinations you are recommended to use Deep Link within the app. You can follow here to implement that.

SampleFragment.kt
navigate(deepLink = "someProtocol://sampleLink".toUri())

Nested Controller

There are some cases when you can have nested controller inside your application.

Let's say you have HomeFragment using BottomNavigationView so you need to create separate navigation graph for the container. Any Fragment you inflate from HomeFragment when they call findNavController will return NavController from HomeFragment for its' navigation graph and not from MainActivity and the main navigation graph.

So how do we get the NavController from the MainActivity? By using hostController from DevFragment.

hostController.navigate(R.id.some_destination_from_main_graph)