So I'm creating my first Android App and I'm already using Jetpack Navigation. I also am implementing my own custom layouts with their own custom toolbars. However, I wanted to take advantage of the built in Jetpack Settings screen i.e. the AndroidX Preference library (https://developer.android.com/develop/ui/views/components/settings).
Because I don't know how big my settings are going to get by the end of this project (don't judge me) I wanted to be able to split my settings across multiple screens as it says here (https://developer.android.com/develop/ui/views/components/settings/organize-your-settings).
But the documentation utilizes fragment factories and emphasize implementation of onPreferenceStartFragment() from an activity. However, my app brings users to the Settings screen via Jetpack Navigation so its already hosted by a Fragment and not an Activity and NavControllers/NavigationGraphs are so far super easy and painless to use.
So can I implement "Split your hierarchy into multiple screens" using a NavController and NavigationGraph?
( I'm going to post an answer, which is what I tried, and so far works)
As promised. This is how I did it. I'm posting because an internet search dindn't find anyone already address the question and since I figured it out I thought it might be helpful to others in the future.
Also, I think its probably obvious to more seasoned Android Developers but I'm new so I'm unsure when things work.
So I'm already using Navigation from a
mainNavHostFragmentlocated in my single activity'sMainActivity.Javafile.And what you have to type to use "Navigation" is so much nicer than using "Fragment Transactions" and "Fragment Factories" so I figured this out so that I could keep using Navigation and avoid using the o.g. Fragment manipulation techniques.
Now when users click the "Settings" icon I provide them, that first
mainNavHostFragmentnavigates the user to aHolderOfSettingsFragment.javaclass.In that
HolderOfSettingsFragment.javaclass I have a secondNavHostFragmentnamedsettingsNavHostFragmentwhich is ...getChildFragmentManagerinstead ofgetSupportFragmentManagerandroidx.fragment.app.FragmentContainerViewin its layout.And in the usual fashion I have a
settingsNavControllergotten from thesettingsNavHostFragment.That
FragmentContainerViewuses anavGraphnamedsub_navigation_from_settingswhich is different than the one my MainActivity uses. The starting fragment insub_navigation_from_settingsis myroot_preferencesand its got a [navigation] action to mySubSettingsExampleFragment.According to the documentation at https://developer.android.com/develop/ui/views/components/settings all you have to do to make a "link" from the root preference screen to an additional screen is list a
<Preference/>tag with anapp:titleentry that will match the<PreferenceCategory>in the "linked" screen as well asapp:fragmentindicating the fragment class to jump to.The Preference Fragments themselves are actually pretty boring. They are literally just a class that extends
PreferenceFragmentCompatwhich implementsonCreatePreferenceswhose single action is to applysetPreferencesFromResourceto appropriate preference resources located in your XML directory.According to the same documentation in order to respond to "link" clicks in the
root_preferncesyou need to implementPreferenceFragmentCompat.OnPreferenceStartFragmentCallback. The documentation says to do this in the Activity but I did it inHolderOfSettingsFragmentand it works just fine.Further, implementing the
PreferenceFragmentCompat.OnPreferenceStartFragmentCallbackinterface means implementing theonPreferenceStartFragmentwhich is called with both acallerand 'pref`. So we do that.To let the
settingsNavHostFragmenthandle things we just check ifpref.getTitlematches a given title and if it does we use thesettingsNavControllerto navigate to the appropriate "Preference Fragment" using the id of the actions in thesub_navigation_from_settingsgraph.Its working just fine for me. Yay!
Its possible that down the line this won't work because of something I don't know causing a conflict but until then I'm glad it works.
I hope this helps someone other than me.
Here is all the code if you want to look at that directly.
Here is the holder java class:
It has the following layout:
Note that the Android Studio Editor will not render this layout and I believe that's because the Settings resources are pure-er XML stored in the XML resource directory.
Here is the second NavGraph:
Here is the root settings XML:
And finally the separate example settings screen's xml: