首页 > 解决方案 > Android导航组件-从一个活动导航(带参数)到第二个,将第二个活动的参数传递给startDestination片段

问题描述

我有一个StartActivity和一个MainActivity

StartActivity负责用户登录。

MainActivity负责用户登录后所能做的一切。

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

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

但如上所述,我的用例略有不同。我希望能够使用导航组件在活动之间导航。我的 2 个活动布局中的每一个都有一个FragmentContainerViewas 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您可以从 导航到MainActivity. SafeArgs正在生成一个StartFragmentDirections使用静态方法调用的类navigateToMain(id: Long)(此调用的参数来自具有 id<argument>的 > 元素中的元素)。我在用户登录后调用此静态方法,并提供用户 ID 作为参数。<activitynav_main

这很好用,我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>

这里的想法是MainActivity's的起始目的地NavHostFragment将是具有 id 的nav_main那个 - 在这种情况下是MainFragment. 现在,我们可以看到,MainFragment还有一个<argument>元素,这意味着 SafeArgs 是为MainFragment. 因此,我想,我可以MainFragment像这样使用委托的 SafeArgs 属性:

私人 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'的 s导航图NavHostFragment确实将sMainActivity作为目的地,而不是MainFragment. 然而,我现在完全不知道我应该如何从一个活动导航到另一个活动,传递数据并将该数据传播到所谓startDestination的第二个活动NavHostFragment导航图......

我知道如何以“老派”的方式做到这一点(intent + extras + 在 onCreate 等中提取额外内容),但我认为这个 Navigation Components 架构的重点是从代码中删除所有杂乱无章的东西,并以更多的方式做事声明方式。

我错过了什么吗?

标签: androidandroid-architecture-navigationandroid-navigationandroid-navigation-graph

解决方案


推荐阅读