多个主机片段-导航Android Jetpack

问题描述 投票:0回答:1

我想拥有多个host_fragment来具有多个bottomNavigationView。其中一个选项卡(Nº2“ Myzone”)转到另一个片段,这是我的第二个host_fragment(“ profile_host_fragment”),它的顶部还有另一个bottomNavigationView。我想做的是这样的:enter image description heremain_nav_graph

<navigation
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="@id/feature_home_nav_graph">
<include app:graph="@navigation/feature_home_nav_graph" />
<include app:graph="@navigation/feature_my_zone_nav_graph" />
<include app:graph="@navigation/feature_catalogue_nav_graph" />
<include app:graph="@navigation/feature_cart_nav_graph" />
<include app:graph="@navigation/feature_support_nav_graph" />

my_zone_nav_graph(配置文件选项卡所在的位置)

<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"
app:startDestination="@id/myZoneFragment"
android:id="@+id/feature_my_zone_nav_graph">

<fragment
    android:id="@+id/myZoneFragment"
    android:name="feature_my_zone.presentation.myzone.MyZoneFragment"
    android:label="fragment_my_zone"
    tools:layout="@layout/fragment_my_zone">

    <action
        android:id="@+id/action_myZoneFragment_to_profileHostFragment"
        app:destination="@id/profileHostFragment" />
</fragment>

<fragment
    android:id="@+id/profileHostFragment"
    android:name="feature_my_zone.presentation.profile.ProfileHostFragment"
    android:label="fragment_profile_host"
    tools:layout="@layout/fragment_profile_host" />

profile_nav_graph

<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/profile_nav_graph.xml"
app:startDestination="@id/addressFragment">

<fragment
    android:id="@+id/addressFragment"
    android:name="feature_my_zone.presentation.profile.address.AddressFragment"
    android:label="fragment_address"
    tools:layout="@layout/fragment_address" />
<fragment
    android:id="@+id/profileFragment"
    android:name="feature_my_zone.presentation.profile.profile.ProfileFragment"
    android:label="fragment_profile"
    tools:layout="@layout/fragment_profile" />
<fragment
    android:id="@+id/paymentsFragment"
    android:name="feature_my_zone.presentation.profile.payments.PaymentsFragment"
    android:label="fragment_payments"
    tools:layout="@layout/fragment_payments" />

<fragment
    android:id="@+id/shippingFragment"
    android:name="feature_my_zone.presentation.profile.shipping.ShippingFragment"
    android:label="fragment_shipping"
    tools:layout="@layout/fragment_shipping" />

这是我的fragment_profile_host

<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="feature_my_zone.presentation.profile.ProfileHostFragment">

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/topNavigationView"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    app:labelVisibilityMode="labeled"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:menu="@menu/profile_nav_menu" />

<fragment
    android:id="@+id/profile_nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:defaultNavHost="true"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/topNavigationView"
    app:navGraph="@navigation/profile_nav_graph" />

并且我试图像在NavHostActivity中一样在ProfileHostFragment上设置导航控制器

  val navController = profile_nav_host_fragment.findNavController()
        topNavigationView.setupWithNavController(navController)

但是我收到以下错误:

Process: game.spa.android.app.v3, PID: 22367
java.lang.IllegalStateException: profile_nav_host_fragment must not be null
    at feature_my_zone.presentation.profile.ProfileHostFragment.setupTopNavigation(ProfileHostFragment.kt:22)
    at feature_my_zone.presentation.profile.ProfileHostFragment.onViewCreated(ProfileHostFragment.kt:17)

我不知道实现此目标的正确方法是什么。感谢您的帮助。

android android-jetpack android-jetpack-navigation
1个回答
1
投票

为什么IllegalStateException发生?

基本上,情况是,当我们嵌套导航主机片段时,从Fragment类中检索子级NavHost fragment会引发此异常。请参阅here

官方文档指出:

fun Fragment.findNavController():NavController

在不是NavHostFragment的片段上或在NavHostFragment将导致IllegalStateException


解决方案是从活动上下文中检索它,并且导航库提供了用于该方法的(参见here

有趣的Activity.findNavController(@IdRes viewId:Int):NavController

根据给定View的ID及其包含的内容找到NavController活动。

在不是NavHost的视图中或在NavHost中调用此视图会导致IllegalStateException。

因此,更改

val navController = profile_nav_host_fragment.findNavController()

val navController = activity.findNavController(R.id.profile_nav_host_fragment)

将帮助解决异常。

© www.soinside.com 2019 - 2024. All rights reserved.