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:
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
.
// 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.
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)