<androidx.fragment.app.FragmentContainerView> 与 <fragment> 作为 NavHost 的视图

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

当使用

androidx.fragment.app.FragmentContainerView
作为导航主机而不是常规
fragment
应用程序无法在方向更改后导航到目的地。

我收到以下错误:

java.lang.IllegalStateException: no current navigation node

是否有我应该知道如何正确使用它的问题,或者我使用导航组件的方式是否不正确?

带视图的简单活动 xml:


...
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:navGraph="@navigation/nav_simple" />
...

导航代码:

<?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/nav_legislator.xml"
    app:startDestination="@id/initialFragment">

    <fragment
        android:id="@+id/initialFragment"
        android:name="com.example.fragmenttag.InitialFragment"
        android:label="Initial Fragment"
        tools:layout="@layout/initial_fragment">
        <action
            android:id="@+id/action_initialFragment_to_destinationFragment"
            app:destination="@id/destinationFragment" />
    </fragment>
    <fragment
        android:id="@+id/destinationFragment"
        android:name="com.example.fragmenttag.DestinationFragment"
        android:label="Destination Fragment"
        tools:layout="@layout/destination_fragment" />

</navigation>

这里是一个 github 存储库,您可以在其中轻松重现错误:https://github.com/dmytroKarataiev/navHostBug

android navigation android-architecture-components
5个回答
41
投票

当没有设置图表并且您尝试调用

no current navigation node
时,会发生
navigate()
错误。如果它仅在您使用
FragmentContainerView
和配置更改后发生,那么这将与 此错误 有关,该错误已修复并计划随 Navigation 2.2.0-rc03 一起发布。

要解决此问题,您可以切换回

<fragment>
或删除
app:navGraph="@navigation/nav_simple"
并改为调用
navController.setGraph(R.navigation.nav_simple)


37
投票

我没有看到任何解释为什么用 FragmentContainerView 替换 Fragment 视图。这就是我添加这个答案的原因(来源如下)。

在活动中托管片段的常见模式之一是使用 FrameLayout。 Android 社区多年来一直这样做,但现在这种情况将会改变。 androidx 团队引入了这个名为 FragmentContainerView 的新视图来为您完成此操作。

您所要做的就是将

FrameLayout
替换为
FragmentContainerView
,一切都应该开箱即用,您无需更改处理片段交易的方式。

这里获得的好处是改进了对片段 z 排序的处理。这是他们使用的示例,但这基本上意味着,例如,两个片段之间的退出和进入转换不会彼此重叠。相反,这个 FragmentContainerView 将首先启动退出动画,然后启动进入动画。

如果您问这可以替换

<fragment>
标签吗?那么答案是肯定的。您所要做的就是在定义
android:name="your_class_name"
时添加
FragmentContainerView
,它将在后台使用
FragmentTransaction
来构建并显示您的片段。这意味着您可以稍后使用片段交易来替换它。

来源

Android 文档


0
投票

我通过对活动类中的 onCreate 方法进行一些更改来解决我的问题

如何处理Fragment(旧用):

    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        val navController = findNavController(R.id.nav_host_fragment_activity_main)
        ...
    }

如何处理FragmentContainerView

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
    
        val navHostFragment = supportFragmentManager
            .findFragmentById(R.id.nav_host_fragment_activity_main) as NavHostFragment

        val navController = navHostFragment.navController
        ...
    }

-2
投票
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    return inflater.inflate(R.layout.frag_splash, container, false)
}

也许您忘记了上面的第三个“false”参数。只有这三个参数

onCreateView
fun可以接受。

android developer website

图片来自:https://developer.android.com/reference/androidx/fragment/app/FragmentContainerView


-2
投票
// drawer layout that I pass is the id of the layout in the activity from which I move to fragment//

SacnFragment sacnFragment = new SacnFragment();
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.drawer_layout, sacnFragment);
    transaction.addToBackStack(null);
    transaction.commit();
© www.soinside.com 2019 - 2024. All rights reserved.