Navigation in multi-module android architecture with arguments

Viewed 1792

Since the navigation files are in app module, feature modules won't have access to the Args file. Is there any workaround for that?

example: if I have a fragment which accepts email and password like so

<fragment
        android:id="@+id/navigation_sample"
        android:name="SampleFragment">
        <argument
            android:name="email"
            app:argType="string" />
        <argument
            android:name="password"
            app:argType="string" />
    </fragment>

I would have a SampleFragmentArgs generated which could be used to navigate

findnavController.navigate(R.id.navigation_sample, SampleFragmentArgs(email, password).toBundle)

But I can use this only from app module not in a feature module

1 Answers

It depends on what you call a "feature module", however I'm assuming that should be android library.

This is the setup that works:

  1. Say your android library is called "mylibrary"
  2. Your "app" module naturally should have the above as dependency
  3. Your "mylibrary" should have apply plugin: "androidx.navigation.safeargs.kotlin" and corresponding setting in classpath of library top level build.gradle
  4. Let's declare navigation graph inside library (say, mylibrary_graph.xml with id myLibraryGraph), just like you'd do in "app" module - and let's assume it has your "SampleFragment" as starting point, with all those arguments listed.
  5. Let's say your "app" module has some navigation graph and let's include "mylibrary_graph.xml" as nested there (<include app:graph="@navigation/mylibrary_graph" />)
  6. Let's say your "app" module nav graph in question has some fragment that needs to jump to your "SampleFragment" inside your android library. We'll declare it like this (pseudo code) :
    <fragment
        android:id="@+id/HelloWorldFragment"
        android:name="..."
        android:label="..."
        tools:layout="...">

        <action
            android:id="@+id/jumpToSampleFragment"
            app:destination="@+id/myLibraryGraph">

          <argument
              android:name="email"
              app:argType="string" />
          <argument
              android:name="password"
              app:argType="string" />
        </action>
    </fragment>
  1. Finally, you can then do this inside your HelloWorldFragment: findNavController().navigate(HelloWorldFragmentDirections.jumpToSampleFragment("oh@acme.com", "nimda"))

As one can see it works but there is somewhat minor inconvenience of declaring arguments in 2 places.

Related