I am using Navigation from Android Jetpack to navigate between screens. Now I want to set startDestination dynamically.
I have an Activity named MainActivity And two Fragments, FragmentA & FragmentB.
var isAllSetUp : Boolean = // It is dynamic and I’m getting this from Preferences. If(isAllSetUp) { // show FragmentA } else { //show FragmentB }
I want to set above flow using Navigation Architecture Component. Currently I have used startDestionation as below but it’s not fulfilling my requirement.
<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/lrf_navigation" app:startDestination="@id/fragmentA"> <fragment android:id="@+id/fragmentA" android:name="com.mindinventory.FragmentA" android:label="fragment_a" tools:layout="@layout/fragment_a" /> </navigation>
Is it possible to set startDestination conditionally using Android Navigation Architecture Component?
The navigation component is a component of the android jetpack that helps us to implement navigation from simple button click to very complex design patterns.
Nowadays mostly developers use the Kotlin language for mobile application development with android clean architecture and due to the architecture of android developers prefer advanced techniques of android like MVVM, ViewBinding, DataBinding, and Dependency Injection, and many more features of the jetpack so here Navigation Component one of them.
Android navigation stack should follow a LIFO structure. With the starting screen at bottom of the stack and the current on top. The up button should never exit your app. With the exception of the bottom element of the stack, the up button should function identically to the system back button.
Google IO 2018 added new components and mixed them with the existing support libraries to create what they now call Android Jetpack — a set of categorised unbundled libraries that can be added according to your application’s needs.
Finally, I got a solution to my query...
Put below code in onCreate()
method of Activity
.
Kotlin code
val navHostFragment = (supportFragmentManager.findFragmentById(R.id.home_nav_fragment) as NavHostFragment) val inflater = navHostFragment.navController.navInflater val graph = inflater.inflate(R.navigation.nav_main) //graph.addArgument("argument", NavArgument) graph.startDestination = R.id.fragment1 //or //graph.startDestination = R.id.fragment2 navHostFragment.navController.graph = graph
Java code
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.home_nav_fragment); // Hostfragment NavInflater inflater = navHostFragment.getNavController().getNavInflater(); NavGraph graph = inflater.inflate(R.navigation.nav_main); //graph.addArgument("argument", NavArgument) graph.setStartDestination(R.id.fragment1); navHostFragment.getNavController().setGraph(graph); navHostFragment.getNavController().getGraph().setDefaultArguments(getIntent().getExtras()); NavigationView navigationView = findViewById(R.id.navigationView); NavigationUI.setupWithNavController(navigationView, navHostFragment.getNavController());
Additional Info
As @artnest suggested, remove the app:navGraph
attribute from the layout. It would look something like this after removal
<?xml version="1.0" encoding="utf-8"?> <FrameLayout 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"> <androidx.fragment.app.FragmentContainerView android:id="@+id/home_nav_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" /> </FrameLayout>
In the case of a fragment
tag used instead of FragmentContainerView
, the above changes remain the same
Some of the APIs have changed, are unavailable or are not necessary since Akash's answer. It's a bit simpler now.
MainActivity.java
:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NavHostFragment navHost = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_main_nav_host); NavController navController = navHost.getNavController(); NavInflater navInflater = navController.getNavInflater(); NavGraph graph = navInflater.inflate(R.navigation.navigation_main); if (false) { graph.setStartDestination(R.id.oneFragment); } else { graph.setStartDestination(R.id.twoFragment); } navController.setGraph(graph); }
activity_main.xml
:
<?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"> <!-- Following line omitted inside <fragment> --> <!-- app:navGraph="@navigation/navigation_main" --> <fragment android:id="@+id/fragment_main_nav_host" android:layout_width="match_parent" android:layout_height="match_parent" android:name="androidx.navigation.fragment.NavHostFragment" /> </androidx.constraintlayout.widget.ConstraintLayout>
navigation_main.xml
:
<?xml version="1.0" encoding="utf-8"?> <!-- Following line omitted inside <navigation>--> <!-- app:startDestination="@id/oneFragment" --> <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/navigation_main" > <fragment android:id="@+id/oneFragment" android:name="com.apponymous.apponymous.OneFragment" android:label="fragment_one" tools:layout="@layout/fragment_one"/> <fragment android:id="@+id/twoFragment" android:name="com.apponymous.apponymous.TwoFragment" android:label="fragment_two" tools:layout="@layout/fragment_two"/> </navigation>
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