我有一个 StartActivity
和一个 MainActivity
。
StartActivity
负责用户登录。
MainActivity
负责用户登录后可以执行的所有操作。
我想使用相对较新的导航组件(导航图、导航控制器等)。
很难找到一些关于如何使用导航组件设置多活动应用程序的官方 Google 文档。他们所有的“如何开始”文档都假设一个活动应用程序,其中包含多个片段,您可以在这些片段之间导航。
但如上所述,我的用例略有不同。我希望能够使用导航组件在活动之间导航。我的 2 个活动布局中的每一个都有一个 FragmentContainerView
作为 NavHostFragment
,并且每个都有自己关联的导航图 XML 文件。
我也在尝试使用 SafeArgs
来传递参数。
这是我的 StartActivity
的 NavHostFragment
的导航图:
<?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)
的类(此调用的参数来自 <argument>
> 元素中的 <activity
元素, id nav_main
)。我在用户登录时调用这个静态方法,提供用户 ID 作为参数。
这很好用,我的 MainActivity
已启动,我可以通过 onCreate
委托属性访问 SafeArgs
中的参数,我已将其声明为类中的私有字段像这样:
private val args: MainActivityArgs by navArgs()
到目前为止,一切都很好。
这是我的 MainActivities
的 NavHostFragment
的导航图:
<?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
的 NavHostFragment
的起始目的地将是 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 中提取额外内容等)执行此操作,但我认为此导航组件架构的重点是消除代码中的所有杂乱并做一些事情以一种更具声明性的方式。
我错过了什么吗?