Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to navigate between two activities using jetpack navigation library

I'm working on a simple app to test out JetPack Navigation in Android. My App have two activities "Activity1" and "Activity2". I'm aware that Jetpack navigation only works for SingleActivity apps but I want to see if there is any solution to my problem. App starts with "Activity1". Below is the navigation xml

<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/mobile_nav"
    app:startDestination="@+id/fragmentA1">

<fragment
        android:id="@+id/fragmentA1"
        android:name="com.example.android.codelabs.navigation.FragmentA1"
        android:label="@string/home"
        tools:layout="@layout/fragment_a_one">

    <action
            android:id="@+id/go_to_fragmentA2"
            app:destination="@+id/fragmentA2"/>

</fragment>


<fragment
        android:id="@+id/fragmentA2"
        android:name="com.example.android.codelabs.navigation.FragmentA2"
        tools:layout="@layout/fragment_a_two">
    <argument
            android:name="flowStepNumber"
            app:argType="integer"
            android:defaultValue="1"/>

    <argument
            android:name="displayName"
            app:argType="string"
            android:defaultValue="Hello"/>


    <action
            android:id="@+id/go_to_fragmentA3"
            app:destination="@+id/fragmentA3"/>

</fragment>


<fragment android:id="@+id/fragmentA3"
          android:name="com.example.android.codelabs.navigation.FragmentA3"
          android:label="fragment_third"
          tools:layout="@layout/fragment_a_three">

    <action android:id="@+id/go_to_activityB"
            app:destination="@id/activityB"/>


</fragment>

<activity android:id="@+id/activityB"
          android:name="com.example.android.codelabs.navigation.registration.ActivityB"
          android:label="activity_registration_main"
          tools:layout="@layout/activity_registration_main">

    <argument android:name="firstName"
              app:argType="string"/>

</activity>
<fragment android:id="@+id/fragmentB1"
          android:name="com.example.android.codelabs.navigation.registration.FragmentB1"
          android:label="fragment_step1"
          tools:layout="@layout/fragment_b_one">

    <argument android:name="firstName"
              app:argType="string"/>

</fragment>

<fragment android:id="@+id/fragmentB2"
          android:name="com.example.android.codelabs.navigation.registration.FragmentB2"
          android:label="fragment_step2"
          tools:layout="@layout/fragment_b_two">

    <argument android:name="lastName"
              app:argType="string"/>

</fragment>

Navigation image for reference

Below is the code from ActivityB

val navController = findNavController(R.id.registration_navHost)
navController.setGraph(R.navigation.mobile_navigation)
navController.navigate(R.id.fragmentB1,safeArgs.toBundle())

Code to get safeArgs in ActivityB

private val safeArgs by navArgs<ActivityBArgs>()

Here are my questions. 1. How can I navigate from ActivityB(FragmentB1) to ActivityA(FragmentA2) Using jetpack Navigation. 2. Is there any way to access the backStack through any Manager Classes in android ?

Why Do I Need Two Activities? FragmentA1,FragmentA2 and FragmentA3 which are part of ActivityA shouldn't have any bottom navigation and drawer layout. Depending on answers selected in these fragments, a bottom navigation and a drawer layout are displayed in ActivityB. On Pressing back button from anywhere on ActivityB, ActivityA should come alive with FragmentA3. Also the toolBar is different for ActivityA and ActivityB

like image 324
Prakash Avatar asked Sep 02 '25 10:09

Prakash


1 Answers

Despite having two Activities, then again I recommend Single Activity apps. I had some testing to separate the Activity because one had BottomNavigation and one without BottomNavigation (Like your issue here). But I always stuck to navigate between the Activities and the backstack always reset (as far as I test it).

Other solution would be Nested NavigationGraph, but I avoid some nested because I think it'll mingle the navigation. So yeah, I try to find another approach and here's what I test and use now.

Some workaround

Let's make a new scenario. I have 3 page that has BottomNavigation (Dashboard, Search, Profile). Then I have a page that doesn't has BottomNavigation, ex. ProfileDetail that opened from Profile. So in this scenario, I'll create:

  1. NavigationHostActivity (Activity that has BottomNavigation)
  2. DashboardFragment (Fragment)
  3. SearchFragment (Fragment)
  4. ProfileFragment (Fragment)
  5. ProfileDetailFragment (Fragment)

I change all my layout became Fragments and when it navigates to any layout, it will check wether they need the BottomNavigation. The basic concept is Show / Hide the BottomNavigation. Here's some example that I use:

NavigationHostActivity

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        this.bind(
            this.findNavController(R.id.navigation_host_fragment),
            this.binding.navigationBottomView
        )
    }

    fun bind(navigationController: NavController, bottomNavigationView: BottomNavigationView) {
        navigationController.addOnDestinationChangedListener { _, destination, _ ->
            this.hideBottomNavigation(bottomNavigationView)

            bottomNavigationView.menu.forEach {
                if (it.itemId == destination.id) {
                    this.showBottomNavigation(bottomNavigationView)
                }
            }
        }
    }


    fun hideBottomNavigation(bottomNavigationView: BottomNavigationView) { bottomNavigationView.visibility = View.GONE }
    fun showBottomNavigation(bottomNavigationView: BottomNavigationView) { bottomNavigationView.visibility = View.VISIBLE }

This will check wether the destination of Navigation is the same as menu of your BottomNavigation. If it's one of the BottomNavigation Menu, then it Show the BottomNavigation.

Actually I put bind, show and hide function in NavigationService, so this is roughly what I did. And this was made for easier example. Feel free to tweak it. I also use DataBinding here FYI.

navigation_host_fragment

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/navigation_bottom_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#FFF"
            app:itemIconSize="22dp"
            app:itemIconTint="@color/state_bottom_navigation_view"
            app:itemTextColor="@color/state_bottom_navigation_view"
            app:labelVisibilityMode="labeled"
            app:layout_constraintBottom_toBottomOf="parent"
            app:menu="@menu/menu_dashboard" />

        <fragment
            android:id="@+id/navigation_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:defaultNavHost="true"
            app:layout_constraintBottom_toTopOf="@id/navigation_bottom_view"
            app:layout_constraintTop_toTopOf="parent"
            app:navGraph="@navigation/navigation_graph" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <data>

        <variable
            name="activity"
            type="*.view.NavigationHostActivity" />
    </data>

</layout>

menu_dashboard

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/dashboardFragment"
        android:title="Dashboard"/>

    <item
        android:id="@+id/searchFragment"
        android:title="Search" />

    <item
        android:id="@+id/profileFragment"
        android:title="Profile" />

</menu>

And that's it, work perfectly for my case. Hope it helps :D

Regards,

Andrea

like image 58
Andrea Lk Avatar answered Sep 05 '25 17:09

Andrea Lk