【问题标题】:Simple navigation across navigation graphs with Android Navigation Architecture Component使用 Android 导航架构组件在导航图上进行简单导航
【发布时间】:2019-01-23 09:20:44
【问题描述】:

这是一个简单的导航设置示例,经过一段时间的研究,我无法使用导航组件库。

假设我有以下屏幕:

顶部的sticky fragment和底部的fragment在各自的导航图中,这里是main_activity.xml:

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/nav_sticky_top"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/navigation_graph_sticky_top" />

    <fragment
        android:id="@+id/navigation_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/nav_sticky_top"
        app:navGraph="@navigation/navigation_graph" />

</androidx.constraintlayout.widget.ConstraintLayout>

当我按下“导航到同级片段”时,它会导航到底部导航图中的同级片段,这是正确的,结果:

这是navigation_graph.xml:

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

    <fragment
        android:id="@+id/blankFragment1"
        android:name="com.example.myapplication.BlankFragment1"
        android:label="fragment_blank_fragment1"
        tools:layout="@layout/fragment_blank_fragment1">

        <action
            android:id="@+id/action_blankFragment1_to_siblingFragment"
            app:destination="@id/siblingFragment" />

    </fragment>

    <fragment
        android:id="@+id/siblingFragment"
        android:name="com.example.myapplication.SiblingFragment"
        tools:layout="@layout/fragment_sibling_fragment" />

</navigation>

现在我想实现“导航到全屏片段”按钮,该按钮应该导航到一个单独的第三个导航图中的全屏片段,并且应该位于粘性片段导航图和其下方的导航图之上。如何正确实现这一目标?我的意思是 没有 hack,比如将顶部导航图片段的可见性设置为 GONE 并在底部导航图中导航到全屏片段。

【问题讨论】:

    标签: android android-architecture-components android-architecture-navigation


    【解决方案1】:

    更新:我不再推荐这种方法。对于小型应用程序,它可能对您有用,但是当我尝试在不同NavHostFragments 中托管的不同导航图之间传递数据时遇到了麻烦。我认为最简单的方法是在顶层布局中隐藏片段以允许全屏视图的“hack”。您可以添加addOnDestinationChangedListener 来监听您想要全屏的目的地,并简单地隐藏所需的片段。

    原始答案: 我在我的应用程序中这样做并且效果很好。您应该使用main_nav_graph.xml 将所有当前片段包装在父片段中。例如:

    <androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <fragment
            android:id="@+id/main_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/main_nav_graph" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    那么您的全屏片段导航将如下所示:

    <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_nav_graph.xml"
        app:startDestination="@id/main_fullscreen">
    
        <fragment
            android:id="@+id/main_fullscreen"
            android:name="com.example.myapplication.MainFullscreen" >
    
            <action
                android:id="@+id/action_main_fullscreen_to_fullscreen2"
                app:destination="@id/fullscreen2" />
    
        </fragment>
    
        <fragment
            android:id="@+id/fullscreen2"
            android:name="com.example.myapplication.Fullscreen2" />
    </navigation>
    

    MainFullscreen 的布局类似于您提供的 ConstraintLayout。只需确保将app:defaultNavHost="true" 添加到您所有的孩子 NavHostFragments。

    然后,当我想从您的 blankFragment1 导航到 fullscreen2 时,我称之为:

    Navigation.findNavController(activity!!, R.id.main_host_fragment).navigate(R.id.action_main_fullscreen_to_fullscreen2)
    

    当然,如果导航图实际上没有连接,除非通过同一个活动进行连接,那么拥有导航图并没有多大意义,但我只是喜欢导航图在导航编辑器中为您提供的应用程序的漂亮图片 :)

    【讨论】:

    • 有趣,我得试试这个。
    • 只是为了警告你。我发现了一个主要问题。硬件后退按钮不会在嵌套导航主机中导航回来:(。等待谷歌的响应
    • 实际上这不是错误。您只需将app:defaultNavHost="true" 添加到NavHostFragments
    • 三个月后我开始测试它,它运行良好,谢谢。我将在下周发布我的应用程序,所以我认为它不会进入这个版本 =)
    • 我不再推荐这种方法。由于不同导航图中存在屏幕,我在应用程序中传递数据时遇到了问题。如果可能的话,我建议在您的应用程序中只使用一个 NavHostFragment。为了实现这一点,我建议使用隐藏片段的“hack”来实现全屏视图。使用 addNavigationListener,我认为这相当干净,缺点更少。
    猜你喜欢
    • 2018-12-22
    • 2018-12-03
    • 2018-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 1970-01-01
    相关资源
    最近更新 更多