Android 导航组件 - 从一个活动导航(使用 args)到第二个活动,将第二个活动的 args 传递给 startDestination 片段

时间:2021-06-23 16:02:05

标签: android android-architecture-navigation android-navigation android-navigation-graph

我有一个 StartActivity 和一个 MainActivity

StartActivity 负责用户登录。

MainActivity 负责用户登录后可以执行的所有操作。

我想使用相对较新的导航组件(导航图、导航控制器等)。

很难找到一些关于如何使用导航组件设置多活动应用程序的官方 Google 文档。他们所有的“如何开始”文档都假设一个活动应用程序,其中包含多个片段,您可以在这些片段之间导航。

但如上所述,我的用例略有不同。我希望能够使用导航组件在活动之间导航。我的 2 个活动布局中的每一个都有一个 FragmentContainerView 作为 NavHostFragment,并且每个都有自己关联的导航图 XML 文件。

我也在尝试使用 SafeArgs 来传递参数。

这是我的 StartActivityNavHostFragment 的导航图:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/start_navigation"
    app:startDestination="@+id/nav_start">

    <fragment
        android:id="@+id/nav_start"
        android:name="com.example.ui.fragments.start.StartFragment"
        android:label="@string/label_start"
        tools:layout="@layout/fragment_start">

        <action
            android:id="@+id/navigate_to_main"
            app:destination="@id/nav_main" />
    </fragment>

    <activity
        android:id="@+id/nav_main"
        android:name="com.example.ui.activities.MainActivity"
        android:label="@string/label_main_activity"
        tools:layout="@layout/activity_main">

        <argument
            android:name="id"
            app:argType="long"
            app:nullable="false" />

    </activity>

</navigation>

所以,这里的想法是,您可以从 StartFragment 导航到 MainActivitySafeArgs 正在使用静态方法 StartFragmentDirections 生成一个名为 navigateToMain(id: Long) 的类(此调用的参数来自 <argument>> 元素中的 <activity 元素, id nav_main)。我在用户登录时调用这个静态方法,提供用户 ID 作为参数。

这很好用,我的 MainActivity 已启动,我可以通过 onCreate 委托属性访问 SafeArgs 中的参数,我已将其声明为类中的私有字段像这样:

private val args: MainActivityArgs by navArgs()

到目前为止,一切都很好。

这是我的 MainActivitiesNavHostFragment 的导航图:

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_navigation"
    app:startDestination="@+id/nav_main">

    <fragment
        android:id="@+id/nav_main"
        android:name="com.example.ui.fragments.main.MainFragment"
        android:label="@string/label_main"
        tools:layout="@layout/fragment_main">

        <argument
            android:name="id"
            app:argType="long"
            app:nullable="false" />

    </fragment>
</navigation>

这里的想法是 MainActivityNavHostFragment 的起始目的地将是 ID 为 nav_main 的那个 - 在本例中为 MainFragment。现在,正如我们所见,MainFragment 也有一个 <argument> 元素,这意味着为 MainFragment 生成了 SafeArgs。因此,我想,我可以像这样在我的 MainFragment 中使用委托的 SafeArgs 属性:

private val args: MainFragmentArgs by navArgs()

这编译得很好(预期 - SafeArgs 大概只是根据导航图 XML 文件中描述的内容生成类...)。但是,当我运行该应用程序时,它崩溃并出现以下错误:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.idlegod/com.example.ui.activities.MainActivity}: java.lang.reflect.InvocationTargetException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
        ....
    Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:52)
        at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:34)

这对我来说并不超级 - 我的意思是我的 StartActivity'NavHostFragment 的导航图确实将 MainActivity 作为目的地,而不是MainFragment。但是,我现在完全不知道我应该如何从一个活动导航到另一个活动,传递数据并将该数据传播到所谓的第二个活动 startDestination 的导航图 NavHostFragment ...

我知道如何以“老派”方式(意图 + 额外 + 在 onCreate 中提取额外内容等)执行此操作,但我认为此导航组件架构的重点是消除代码中的所有杂乱并做一些事情以一种更具声明性的方式。

我错过了什么吗?

0 个答案:

没有答案