Dynamic nav graph in Jetpack Navigation
Google’s Jetpack initiative is truly amazing. Throughout past several years it made tremendous progress, which will be culminated by stable release of Jetpack Compose.
Yet there are sometimes gaps, obscure parts in their libraries.
Recently I had to implement dynamic navigation, i.e. first app screen is selected based on some logic inside Activity’s onCreate.
As application is screen-based, Jetpack Navigation is a natural choice.
For static nav graph, you simply set navigation xml in NavHostFragment.
For dynamic nav graph, you need to set navigation xml manually.
First step is to obtain NavController. It appeared that inside Activity’s onCreate calling findNavController will yield IllegalStateException. There is even bug filed on Google’s issue tracker. Workaround is simple:
Second step was to create function that you call from within onCreate when savedInstanceState is null.
Here you need to pay attention that AppBarConfiguration has two topmost destinations. It is needed for Toolbar to correctly show current fragment’s label.
Now you may wonder what to call when you have recreated state (savedState is not null) ?
Answer is to set nav graph again and set random start destination too (to avoid IllegalStateException).
State restoration is perplexing at first as docs do not mention dynamic nav graph creation. After that I stumbled on this bug on Google’s issue tracker, from which I undesrtood that setGraph is actually in charge of state restoration.
Javadoc for this method says “Any current navigation graph data (including back stack) will be replaced” which is example of misleading documentation :)
Happy Jetpack coding!