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>
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
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.
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:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With