37

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

应用模块结构

我还没有找到任何关于多模块导航的官方文档,但是我找到了这篇文章,所以这就是我的 gradle 文件的样子:

功能 1 - 细节

...
implementation project(":base")
implementation project(":feature-2-detail")
...

功能 2 - 细节

...
implementation project(":base")
implementation project(":feature-1-detail")
...

特色 3 - 细节

...
implementation project(":base")
implementation project(":feature-1-detail")
...

这是我的导航图:

功能 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>

功能 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>

特色 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>

所以一切都适用于这种设置,但这里的问题是要将模块连接到另一个模块,我们必须将另一个功能添加为当前功能的依赖项。就像我的情况一样,功能 1 - 详细信息可以转到功能 2 - 详细信息,反之亦然,这样做给了我在 gradle 中的循环依赖。

还有其他方法可以进行多模块导航吗?我试过使用深层链接,但无济于事。

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

4

3 回答 3

32

这已经是一年之久,但该库现在可以支持这个确切的用例!从2.1.0-alpha03 开始​​,我们可以导航深度链接 URI。

与其将功能作为实现细节相互添加,我们可以让它们彼此之间不知道并使用深度链接导航。

功能 1 - 细节 - build.gradle

dependencies {
    implementation project(':base')
}

Feature 2 - Detail相同。它不需要知道其他模块。

要进行模块间导航,我们必须首先定义用于通过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>

功能 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>

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

所以在Feature 1 - Detail的片段中,也许是点击按钮?必须执行导航的任何地方

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

功能 2 - 细节中,

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

瞧!模块间导航。

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

虽然我没有在更复杂的项目上尝试过,但我喜欢这个库,我希望看到这个库更加成熟!

我为此创建了一篇 Medium 文章。你可以看看它。干杯!

于 2019-08-14T07:30:55.347 回答
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

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

于 2019-03-20T10:52:27.197 回答
3

当您在基本功能中显式声明每个功能导航图 ID 时,可以删除所有 Gradle 功能间依赖关系。我对这个解决方案不是 100% 满意,因为这些 ID 创建了“隐藏的”功能间依赖关系,但除此之外它工作正常。

以下是此设置的关键部分:

:应用程序

构建.gradle

dependencies {
    implementation project(':features:feature-base')
    implementation project(':features:feature-one')
    implementation project(':features:feature-two')
}

:features:feature-base

构建.gradle

dependencies {
    application project(':app')
    feature project(':features:feature-one')
    feature project(':features:feature-two')
}

导航/feature_base_nav_graph.xml

<navigation ...>
    <include app:graph="@navigation/feature_one_nav_graph" />
    <include app:graph="@navigation/feature_two_nav_graph" />
</navigation>

值/feature_base_ids.xml

<resources>
    <item name="feature_one_nav_graph" type="id" />
    <item name="feature_two_nav_graph" type="id" />
</resources>

:features:feature-one

构建.gradle

dependencies {
    implementation project(':features:feature-base')
}

导航/feature_one_nav_graph.xml

<navigation
    android:id="@id/feature_one_nav_graph"
    ...>

    <fragment
        android:id="@+id/oneFragment"
        ...>
        <action
            android:id="@+id/navigateToFeatureTwo"
            app:destination="@id/feature_two_nav_graph"
            ... />
    </fragment>

</navigation>

导航

findNavController().navigate(R.id.navigateToFeatureTwo)

:features:feature-二

构建.gradle

dependencies {
    implementation project(':features:feature-base')
}

导航/feature_two_nav_graph.xml

<navigation
    android:id="@id/feature_two_nav_graph"
    ...>

    <fragment
        android:id="@+id/twoFragment"
        ...>
        <action
            android:id="@+id/navigateToFeatureOne"
            app:destination="@id/feature_one_nav_graph"
            ... />
    </fragment>

</navigation>

导航

findNavController().navigate(R.id.navigateToFeatureOne)
于 2018-07-31T15:13:45.753 回答