【问题标题】:Multiple Host Fragments - Navigation Android Jetpack多个主机片段 - 导航 Android Jetpack
【发布时间】:2019-12-04 22:21:55
【问题描述】:

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

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

【问题讨论】:

  • 尽管有profile_nav_host_fragment.findNavController(),请尝试从activity.findNavController(R.id.profile_nav_host_fragment) 等活动上下文中使用NavHost。
  • 非常感谢@JeelVankhede 的回答。 Thatth 解决了我的问题,如果您想回答,我会将其标记为已接受。

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


【解决方案1】:

为什么会出现IllegalStateException

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

官方文档指出:

fun Fragment.findNavController(): NavController

在不是 NavHostFragment 的 Fragment 或在 NavHostFragment 将导致 IllegalStateException


解决方案是从 活动上下文 中检索它,导航库为此提供了方法(参考here

fun Activity.findNavController(@IdRes viewId: Int): NavController

在给定 View 的 id 及其包含的情况下查找 NavController 活动。

在非 NavHost 或 NavHost 内的 View 上调用它会 导致 IllegalStateException。

所以,改变

val navController = profile_nav_host_fragment.findNavController()

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

将有助于解决异常。

【讨论】:

  • 乐于助人 ?
猜你喜欢
  • 2019-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多