12

I'm trying to implement the new navigation component with dynamic features

So the structure looks like this:

  • app (has dynamic dynamicFeatures = [] included in gradle)
  • features

    • login
    • home
    • etc.
  • library -> globalNav

I've been reading a lot with no success how to glue these together without depending on each other as each feature is completely isolated

e.g The app (app module) starts with the SplashActivity and checks the session state, so my question is how should I start the login_graph or home_graph and in the first case, start the home after finishing the auth flow?

The way I'm currently trying gluing'em together is using a globalNav module (android-library) I found a couple of workarounds:

  • Complete classpath, meaning I start the intent with the className (bad as this is not really scalable and makes maintaining a PITA)
Intent().setClassName(context.packageName, className).also { context.startActivity(it) }
  • Deeplinks (the one I wanted to use as my nav graph already has those) but for some reason, it always shows the "Choose complete action" picker even though only my app takes it.

    • I've already tried using actions but the same behavior as deeplinks

Any suggestions would be great :)


PS: Some references that I've been viewing/reading on:

PSS: I'm actively trying to figure this out if I find a good solution I'll make sure to answer too.

EDIT

For anyone interested in this, as it isn't currently supported, you can star the issue here: https://issuetracker.google.com/issues/132170186

Joaquim Ley
  • 4,038
  • 2
  • 24
  • 42
  • Have you specified the package name of your app when navigating via deeplinks? This should solve your issue with the picker. – Oscar Spruit Apr 15 '19 at 08:46
  • Thanks for the reply, and yes :). There's the `context.packageName` too strict the intent to the current application's package. The behavior is quite strange as the chooser shows up but resolves immediately. – Joaquim Ley Apr 15 '19 at 11:04

3 Answers3

3

Navigation in on-demand feature modules is supported by using the navigation-dynamic-feature-* components. The most recent version can be found on maven.google.com.

We do have a sample available that demonstrates both XML and Kotlin DSL declaration possibilites.

The documentation is available here

For more info you can also watch the recording on this from the Android Dev Summit 2019.

Ben Weiss
  • 17,182
  • 6
  • 67
  • 87
  • Thanks for sharing the development here @keyboardsurfer . Eagerly awaiting for the stable release. I recommend anyone interested in this matter to watch the talk linked above. – Joaquim Ley Oct 29 '19 at 10:49
  • 1
    Hey, @keyboardsurfer would you be so kind with your time to update this answer with the official implementation (DynamicFragment etc.)? This way we would have a Google(r) reply and I could accept with confidence as the correct answer. – Joaquim Ley Sep 25 '20 at 14:00
  • @JoaquimLey thanks for flagging this with me. Updated to the latest info. – Ben Weiss Sep 28 '20 at 11:05
  • 1
    Thanks for updating! Marking it, although SO discourages direct links one can assume these shouldn't break? – Joaquim Ley Sep 28 '20 at 18:04
1

This is now supported in androidx.navigation:navigation-dynamic-features-fragment:2.3.0.

Just include app:moduleName in navigation.

Example:

<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/menu_nav_graph"
    app:startDestination="@id/main_fragment">

<!-- this fragment is in base module -->
<fragment
        android:id="@+id/main_fragment"
        android:name="com.example.app.MainFragment"
        tools:layout="@layout/fragment_main" />

<!-- activity and fragment in a different module -->
<activity
        android:id="@+id/splash_activity"
        android:name="com.example.examplemodule.splash.SplashActivity"
        app:moduleName="examplemodule" />

<fragment
        android:id="@+id/user_profile"
        android:name="com.example.examplemodule.user.UserProfileFragment"
        android:label="UserProfileFragment"
        app:moduleName="examplemodule" />

</navigation>

You can call findNavController().navigate(R.id.splash_activity) from anywhere, and it will install examplemodule for you if necessary.

Torkel Velure
  • 1,217
  • 10
  • 17
0

I was also facing with same problem couple minutes ago and I saw your question while trying to find an answer.

In my case I am having 2 modules app and login. The module login is dynamic-feature module which depends on module app. The module login contains all the logic and navigation for logging purpose (it contains login, register and so on). I wanted to include this LoginActivity (which is an activity in login module which has all navigation in it) in the main navigation graph in app module. We can not call LoginActivity from app layer which it does not know about it. But

<activity android:id="@+id/loginActivity"
    android:name="login.LoginActivity"
    android:label="LoginActivity"/>

adding it manually in main nav graph worked for me.

Samuel Philipp
  • 10,631
  • 12
  • 36
  • 56
  • That's what I meant with ``` Complete classpath, meaning I start the intent with the className (bad as this is not really scalable and makes maintaining a PITA) ``` Thanks for your input though :), the problem with this approach is: If you want to call the login activity from anywhere else, you have to copy paste. and if you change the activity name (or path) everything goes ape, seems like Google will implement their own solution for this though :) – Joaquim Ley May 14 '19 at 13:47