多个主机片段-导航Android Jetpack

时间:2019-12-04 13:01:21

标签: android android-jetpack android-jetpack-navigation

我想拥有多个host_fragment以具有多个bottomNavigationView。其中一个选项卡(Nº2“ Myzone”)转到另一个片段,这是我的第二个host_fragment(“ profile_host_fragment”),它的顶部还有另一个bottomNavigationView。 我想做的是这样的: enter image description here main_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)

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

1 个答案:

答案 0 :(得分:1)

为什么IllegalStateException发生了?

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

  

官方文档指出:

     

fun Fragment.findNavController():NavController

     

在不是NavHostFragment的Fragment上或在   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)

将有助于解决该异常。