
1. Overview
In this article, we will learn to use the Android navigation component with multiple activities. If you also want a high-level overview of the concepts, refer to the Android Navigation component article.
For using a single activity with multiple fragments, refer Android navigation component example.
2. Android navigation component multiple activities
A navigation component is for apps that use a single activity to swap multiple fragments. The single activity contains a NavHostFragment
layout container to display the fragments. We associate it with the navigation graph, which contains the information required for navigation such as fragments (Destinations).
We recommend using a single activity model with multiple fragments. But if you still need to use the navigation component with multiple activities, then you can do it.
- Refer section 3 if all your activities contain fragments
- Refer section 4 if your destination activity don’t have any fragment.
2.1. Set up project
1. Android navigation component requires Android Studio 3.3 or higher
2. Add Java 8 feature to your project:
android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } }
android { ... compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } }
3. Add the required dependencies to your app’s build gradle
file.
dependencies { def nav_version = "2.3.5" implementation "androidx.navigation:navigation-fragment:$nav_version" implementation "androidx.navigation:navigation-ui:$nav_version" implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version" androidTestImplementation "androidx.navigation:navigation-testing:$nav_version" implementation "androidx.navigation:navigation-compose:2.4.0-alpha10" }
dependencies { val nav_version = "2.3.5" implementation("androidx.navigation:navigation-fragment:$nav_version") implementation("androidx.navigation:navigation-ui:$nav_version") implementation("androidx.navigation:navigation-fragment-ktx:$nav_version") implementation("androidx.navigation:navigation-ui-ktx:$nav_version") implementation("androidx.navigation:navigation-dynamic-features-fragment:$nav_version") androidTestImplementation("androidx.navigation:navigation-testing:$nav_version") implementation("androidx.navigation:navigation-compose:2.4.0-alpha10") }
3. Android navigation component multiple activities with fragments
If your activities have fragments, then follow this approach.
It is possible to use the navigation component with multiple activities using the Nested navigation graphs. Thus, you can associate each activity with a navigation graph.
Let’s see a simple example with two activities: MainActivity
with fragment MainFragment
and DestinationActivity
with fragment DestinationFragment
.
You should also add your DestinationActivity
navigation graph to the MainActivity
graph. Then instruct the navigation controller to navigate from Main to Destination activity.
3.1. Add activities and fragments
The activities don’t have any specific code for navigation.
The MainActivity
layout contains the NavHostFragment
container to show the fragments. The MainFragment
has code to instruct the navigation controller to navigate to the DestinationFragment
when the user clicks on the "Navigate"
button.
MainActivity
file
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }
Main activity xml
The main activity is the container to show the fragments. So, specify the NavHostFragment
in the main activity XML file as below:
<?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=".MainActivity"> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:defaultNavHost="true" app:navGraph="@navigation/main_nav_graph" /> </androidx.constraintlayout.widget.ConstraintLayout>
MainFragment
file
class MainFragment : Fragment() { override fun onResume() { super.onResume() navigate_to_second.setOnClickListener { Navigation.findNavController(it).navigate(R.id.action_navigate) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_main, container, false) } }
Main Fragment xml file
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".MainFragment"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/main_fragment" android:layout_gravity="center"/> <Button android:id="@+id/navigate_to_second" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/navigate_to_second" android:layout_gravity="center|bottom"/> </FrameLayout>
DestinationActivity
file
class DestinationActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_destination) } }
DestinationActivity
xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/destination_activity" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
DestinationFragment
file
class DestinationFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_destination, container, false) } }
DestinationFragment
XML
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".DestinationFragment"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:text="@string/destination_fragment" /> </FrameLayout>
3.2. Add navigation graph
main_nav_graph
The MainActivity's
navigation graph includes nested navigation graph destination_nav_graph
. Also, the MainFragment
contains action action_navigate
pointing to the DestinationActivity
.
So when the user clicks on the "Navigate"
button in the MainActivity
, then the navigation controller uses this action_navigate
and navigates to the DestinationFragment
correctly.
<?xml version="1.0" encoding="utf-8"?> <navigation 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:id="@+id/main_navigation" app:startDestination="@id/mainFragment"> <include app:graph="@navigation/destination_nav_graph" /> <fragment android:id="@+id/mainFragment" android:name="com.tedblob.kotlin.navigationcomponentmultipleactivities.MainFragment" android:label="fragment_main" tools:layout="@layout/fragment_main"> <action android:id="@+id/action_navigate" app:destination="@id/destination_activity" /> </fragment> </navigation>
destination_nav_graph
The DestinationActivity
is associated with destination_nav_graph
and the start destination is DestinationFragment
.
<?xml version="1.0" encoding="utf-8"?> <navigation 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:id="@+id/destination_activity" app:startDestination="@id/destinationFragment"> <fragment android:id="@+id/destinationFragment" android:name="com.tedblob.kotlin.navigationcomponentmultipleactivities.DestinationFragment" android:label="fragment_destination" tools:layout="@layout/fragment_destination" /> </navigation>
4. Android navigation component multiple activities without fragment
Assume you have a MainActivity
with fragments. Also, from the MainActivity
, you want to navigate to another activity DestinationActivity
that doesn’t have any fragments. You can do it by following the below steps:
1. Add your DestinationActivity
using <activity>
to your navigation graph associated with your MainActivity:
<activity android:id="@+id/destinationActivity" android:name="com.tedblob.kotlin.navigationcomponentmultipleactivities.DestinationActivity" android:label="DestinationActivity" />
2. Add an action to the fragment element from where you want to navigate to the DestinationActivity
. For example, when you click on a button in the MainFragment
, it should take you to the DestinationActivity
.
<fragment android:id="@+id/mainFragment" android:name="com.tedblob.kotlin.navigationcomponentmultipleactivities.MainFragment" android:label="fragment_main" tools:layout="@layout/fragment_main"> <action android:id="@+id/action_navigate3" app:destination="@id/destinationActivity" /> </fragment>
3. In your fragment, inform the navigation controller to use the action to navigate to the DestinationActivity
.
Navigation.findNavController(it).navigate(R.id.action_navigate3)
You can continue reading for the complete code of this example.
4.1. Add activities and fragments
The activities don’t have any specific code for navigation.
The MainActivity
layout contains the NavHostFragment
container to show the fragments, and the MainFragment
has code to instruct the navigation controller to navigate to the DestinationFragment
when the user clicks on the “Navigate” button.
MainActivity file
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }
Main activity xml
The Main activity is the container to show the fragments. So specify the NavHostFragment
in the main activity XML file as below:
<?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=".MainActivity"> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:defaultNavHost="true" app:navGraph="@navigation/main_nav_graph" /> </androidx.constraintlayout.widget.ConstraintLayout>
MainFragment file
class MainFragment : Fragment() { override fun onResume() { super.onResume() navigate_to_second.setOnClickListener { Navigation.findNavController(it).navigate(R.id.action_navigate3) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_main, container, false) } }
Main Fragment xml file
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" tools:context=".MainFragment"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/main_fragment" android:layout_gravity="center"/> <Button android:id="@+id/navigate_to_second" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/navigate_to_second" android:layout_gravity="center|bottom"/> </FrameLayout>
DestinationActivity file
class DestinationActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_destination) } }
DestinationActivity xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/destination_activity" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
4.2. Add navigation graph
main_nav_graph
The MainActivity's
navigation graph includes activity DestinationActivity
. Also, the MainFragment
contains action action_navigate
pointing to the DestinationActivity
.
So when user clicks on the “Navigate” button in the MainActivity
, then the navigation controller uses this action_navigate
and navigates to the DestinationActivity
correctly.
<?xml version="1.0" encoding="utf-8"?> <navigation 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:id="@+id/main_navigation" app:startDestination="@id/mainFragment"> <fragment android:id="@+id/mainFragment" android:name="com.tedblob.kotlin.navigationcomponentmultipleactivities.MainFragment" android:label="fragment_main" tools:layout="@layout/fragment_main"> <action android:id="@+id/action_navigate3" app:destination="@id/destinationActivity" /> </fragment> <activity android:id="@+id/destinationActivity" android:name="com.tedblob.kotlin.navigationcomponentmultipleactivities.DestinationActivity" android:label="DestinationActivity" /> </navigation>
5. Conclusion
To sum up, we have learned to use the Navigation component with multiple activities.