使用架构组件进行多模块导航

Kur*_*sta 13 android android-architecture-components android-architecture-navigation

所以我在我当前的应用程序中为我的模块设置了这个结构.

应用模块结构

我还没有找到任何有关多模块导航的官方文档,但我发现这篇文章的内容是关于这一点的,这里是我的gradle文件的方式:

特征1 - 细节

...
implementation project(":base")
implementation project(":feature-2-detail")
...
Run Code Online (Sandbox Code Playgroud)

特征2 - 细节

...
implementation project(":base")
implementation project(":feature-1-detail")
...
Run Code Online (Sandbox Code Playgroud)

特征3 - 细节

...
implementation project(":base")
implementation project(":feature-1-detail")
...
Run Code Online (Sandbox Code Playgroud)

这是我的导航图:

特征1 - 细节

<navigation ...
    android:id="@+id/graph_feature_1_id">
    <include app:graph="@navigation/graph_feature_2" />
    <fragment ...
        android:id="@+id/nav_feature_1">
        <action ...
            app:destination="@+id/graph_feature_2_id" />

    </fragment>
</navigation>
Run Code Online (Sandbox Code Playgroud)

特征2 - 细节

<navigation ...
    android:id="@+id/graph_feature_2_id">
    <include app:graph="@navigation/graph_feature_1" />
    <fragment ...
        android:id="@+id/nav_feature_2">
        <action ...
            app:destination="@+id/graph_feature_1_id" />

    </fragment>
</navigation>
Run Code Online (Sandbox Code Playgroud)

特征3 - 细节

<navigation ...
    android:id="@+id/graph_feature_3_id">
    <include app:graph="@navigation/graph_feature_1" />
    <fragment ...
        android:id="@+id/nav_feature_3">
        <action ...
            app:destination="@+id/graph_feature_1_id" />

    </fragment>
</navigation>
Run Code Online (Sandbox Code Playgroud)

所以一切都适用于这种设置,但问题是将模块连接到另一个模块,我们必须添加另一个功能作为当前功能的依赖.就像在我的情况下,功能1 - 细节可以转到功能2 - 细节,反之亦然,这样做可以让我在gradle中获得循环依赖.

还有另一种方法可以进行多模块导航吗?我尝试过使用深层链接,但无济于事.

任何帮助,将不胜感激!谢谢!

doo*_*e89 8

一种可能有用的方法是创建一个全新的独立模块(例如":navigation" 模块)并将所有其他模块中的所有navigation.xml 文件移动到该模块中。然后我们在需要导航相关内容的所有其他模块中依赖新的 (":navigation") 模块,我们将能够访问它的 R.navigation 或生成的参数类等。

由于新的 (":navigation") 模块不知道项目 IDE 中的任何其他内容,因此我们将在 navigation.xml 文件中使用的任何片段、活动和其他类标记为红色,这些类在其他模块外部定义,但只要我们使用完整的类名 (com.exampel.MyFragment) 它将编译和工作。

<?xml version="1.0" encoding="utf-8"?>
<navigation 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph_id"
    app:startDestination="@id/some_navigation_id">

    <fragment
        android:id="@+id/some_navigation_id"
        android:name="com.exampel.MyFragment".../>
        // com.exampel.MyFragment will be marked red since IDE can't link it
        // to the existing class because it is in the other module
Run Code Online (Sandbox Code Playgroud)

这会以一种我们需要知道类名和潜在参数的方式创建对我们想要导航到的所有类的“隐藏”依赖,我们必须手动维护它,但它允许我们轻松地在独立模块中分离导航。


Kur*_*sta 6

已经有一年的时间了,但是库现在可以支持这个确切的用例!从2.1.0-alpha03开始,我们可以浏览深层链接URI。

不必将功能作为彼此的实现细节添加,我们可以使它们之间互不了解,并使用深度链接导航。

功能1-详细信息-build.gradle

dependencies {
    implementation project(':base')
}
Run Code Online (Sandbox Code Playgroud)

功能2-细节相同。无需知道其他模块。

要进行模块间导航,我们必须首先定义用于通过deepLink标签导航到该目的地的深层链接。

功能1-详细信息-导航图

<navigation ...
    android:id="@+id/graph_feature_1_detail_id">
    <fragment ...
        android:id="@+id/nav_feature_1_detail">
        <deepLink app:uri="myApp://feature1detail"/>

    </fragment>
</navigation>
Run Code Online (Sandbox Code Playgroud)

功能2-详细信息-导航图

<navigation ...
    android:id="@+id/graph_feature_2_detail_id">
    <fragment ...
        android:id="@+id/nav_feature_2_detail">
        <deepLink app:uri="myApp://feature2detail"/>

    </fragment>
</navigation>
Run Code Online (Sandbox Code Playgroud)

现在,我们已设置了URI的深层链接,我们可以直接在 NavController

因此,在“ 功能1-详细信息”的片段中,也许单击按钮即可?您必须执行导航的任何地方

class Feature1DetailFragment {
   fun onViewCreated(...) {
       ...
       view.setOnClickListener {
           val uri = Uri.parse("myApp://feature2detail")
           findNavController().navigate(uri)
       }
   }
}

Run Code Online (Sandbox Code Playgroud)

功能2-详细信息中

class Feature2DetailFragment {
   fun onViewCreated(...) {
       ...
       view.setOnClickListener {
           val uri = Uri.parse("myApp://feature1detail")
           findNavController().navigate(uri)
       }
   }
}

Run Code Online (Sandbox Code Playgroud)

瞧!模块间导航。

在撰写本文时,最新的稳定版本是2.1.0-rc01

尽管我还没有在更复杂的项目上尝试过这个,但是我喜欢这个库,并且希望看到这个库更加成熟!

我为此撰写了一篇中型文章。您可以看一下。干杯!