Android导航组件多个Nav主机

发布于 2025-01-12 11:06:42 字数 8747 浏览 0 评论 0原文

我在项目中使用单个 Activity 模式。在其中一个片段中,我们将其称为 ExploreFragment(),我需要创建一个 FragmentContainerView,其中多个片段将发生变化。 ExploreFragment() 有一个搜索引擎,默认情况下显示带有流派列表的 MovieGanresFragment()。如果我开始在搜索引擎中输入文本,片段将更改为 MovieByNameFragment(),其中显示具有用户输入名称的电影列表。问题是,如何实现 ExploreFragment() ,其中将有一个包含多个片段的容器,并且所有这些都使用导航组件?

我决定在主图中创建一个 ExploreFragment() 并在其中创建一个 FragmentContainerView 来切换两个片段 MovieGanresFragment()>MovieByNameFragment() 。对于在 ExploreFragment() 中切换片段,我使用 childFragmentManager

 private fun switchFragment(movieName: String) {

        val searchMovieByNameFragment =   SearchMovieByNameFragment.newInstanceSearchMovieByNameFragment(movieName)

        openScreenWithMovies(searchMovieByNameFragment)

        childFragmentManager.beginTransaction()
            .replace(
                R.id.fragment_container_explore,
                searchMovieByNameFragment
            )
            .addToBackStack(null)
            .commit()
    }

它有效,但还有另一个问题。如何从不在主图中的 MovieByNameFragment() 片段导航到位于主图中的 MoieDetailsFragment() 片段并将数据传递到那里?

这是导航 XML

<?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/mobile_navigation"
    app:startDestination="@id/welcome_screen">

    <fragment
        android:id="@+id/moviesFragment"
        android:name="com.example.movies.ui.movies.MoviesFragment"
        android:label="Home"
        tools:layout="@layout/fragment_movies">
        <action
            android:id="@+id/action_moviesFragment_to_movieDetailsFragment"
            app:destination="@id/movieDetailsFragment"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right" />
        <action
            android:id="@+id/action_homeFragment_to_moviesFilterFragment"
            app:destination="@id/moviesFilterFragment"
            app:enterAnim="@anim/enter_from_top"
            app:exitAnim="@anim/exit_to_bottom" />

    </fragment>
    <fragment
        android:id="@+id/movieDetailsFragment"
        android:name="com.example.movies.ui.move_details.MovieDetailsFragment"
        tools:layout="@layout/fragment_movie_details" >
        <argument
            android:name="movieId"
            app:argType="integer"/>
        <argument
            android:name="showSavedIcon"
            app:argType="boolean"/>
        <action
            android:id="@+id/action_movieDetailsFragment_self"
            app:destination="@id/movieDetailsFragment"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right" />
    </fragment>
    <fragment
        android:id="@+id/saved_movies"
        android:name="com.example.movies.ui.saved_movie.SavedMovieFragment"
        android:label="Watch list"
        tools:layout="@layout/fragment_saved_movie">
        <action
            android:id="@+id/action_saved_movies_to_movieDetailsFragment"
            app:destination="@id/movieDetailsFragment"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right" />
    </fragment>
    <fragment
        android:id="@+id/nav_login_fragment"
        android:name="com.example.movies.ui.login.LoginFragment"
        android:label="fragment_login"
        tools:layout="@layout/fragment_login">
        <action
            android:id="@+id/action_nav_login_fragment_to_homeFragment"
            app:destination="@id/moviesFragment"
            app:popUpTo="@id/nav_login_fragment"
            app:popUpToInclusive="true"/>
    </fragment>
    <fragment
        android:id="@+id/settings"
        android:name="com.example.movies.ui.settings.SettingsFragment"
        android:label="Settings">
        <action
            android:id="@+id/action_settings_to_nav_login_fragment"
            app:destination="@id/nav_login_fragment"
            app:popUpTo="@id/moviesFragment"
            app:popUpToInclusive="true"/>
    </fragment>
    <fragment
        android:id="@+id/welcome_screen"
        android:name="com.example.movies.ui.welcome_screen.WelcomeScreenFragment"
        android:label="fragment_welcome_screen"
        tools:layout="@layout/fragment_welcome_screen">
        <action
            android:id="@+id/action_welcomeScreenFragment_to_nav_login_fragment"
            app:destination="@id/nav_login_fragment"
            app:popUpTo="@id/welcome_screen"
            app:popUpToInclusive="true" />
        <action
            android:id="@+id/action_welcome_screen_to_homeFragment"
            app:destination="@id/homeFragment"
            app:popUpTo="@id/welcome_screen"
            app:popUpToInclusive="true"/>
    </fragment>
    <fragment
        android:id="@+id/moviesFilterFragment"
        android:name="com.example.movies.ui.movie_filter.MoviesFilterFragment"
        tools:layout="@layout/fragment_movies_filter">
        <action
            android:id="@+id/action_moviesFilterFragment_to_homeFragment"
            app:destination="@id/moviesFragment"
            app:popUpTo="@id/moviesFragment"
            app:popUpToInclusive="true" />
    </fragment>
    <fragment
        android:id="@+id/homeFragment"
        android:name="com.example.movies.ui.home.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@+id/action_homeFragment_to_moviesFragment"
            app:destination="@id/moviesFragment" />
        <action
            android:id="@+id/action_homeFragment_to_movieDetailsFragment"
            app:destination="@id/movieDetailsFragment"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right" />
    </fragment>
    <fragment
        android:id="@+id/explore_fragment"
        android:name="com.example.movies.ui.explore.ExploreFragment"
        android:label="Explore"
        tools:layout="@layout/fragment_explore">
        <action
            android:id="@+id/action_exploreFragment_to_moviesFragment"
            app:destination="@id/moviesFragment" />
    </fragment>


</navigation>

这是 ExploreFragment() 的 XML


<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"
    android:orientation="vertical"
    tools:context=".ui.explore.ExploreFragment">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/home_page_toolbar_color"
        android:theme="@style/ToolBarStyle"
        android:elevation="4dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.cardview.widget.CardView
        android:id="@+id/card_view_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        app:cardCornerRadius="32dp"
        app:cardElevation="12dp"
        app:layout_constraintTop_toBottomOf="@id/toolbar">

        <androidx.appcompat.widget.SearchView
            android:id="@+id/search_view"
            android:layout_width="match_parent"
            android:layout_height="34dp"
            android:background="@drawable/background_search_view"
            app:iconifiedByDefault="false"
            app:queryHint="@string/search_view_hint"
            tools:ignore="RtlSymmetry" />
    </androidx.cardview.widget.CardView>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container_explore"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="15dp"
        android:name="com.example.movies.ui.movie_categories.MovieCategoriesFragment"
        app:layout_constraintTop_toBottomOf="@id/card_view_search"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

I use single Activity patern in my project.In one of the fragments, let's call it ExploreFragment(), I need to create a FragmentContainerView where several fragments will change. The ExploreFragment() has a search engine and by default displays a MovieGanresFragment() with a list of genres. If I start typing text into the search engine, the fragment changes to MovieByNameFragment() where a list of movies with the name entered by the user is displayed. The question is, how do I implement ExploreFragment() where there will be a container with several fragments and all this using the Navigation component?

I decided to create a ExploreFragment() in the main graph and create a FragmentContainerView in it to switch the two fragments MovieGanresFragment() and MovieByNameFragment() . For switching fragments in ExploreFragment() I use childFragmentManager

 private fun switchFragment(movieName: String) {

        val searchMovieByNameFragment =   SearchMovieByNameFragment.newInstanceSearchMovieByNameFragment(movieName)

        openScreenWithMovies(searchMovieByNameFragment)

        childFragmentManager.beginTransaction()
            .replace(
                R.id.fragment_container_explore,
                searchMovieByNameFragment
            )
            .addToBackStack(null)
            .commit()
    }

It works, but there was another question. How to navigate from the MovieByNameFragment() fragment which is not in the main graph to the MoieDetailsFragment() fragment which is in the main graph and pass the data there?

Thsi is navigation XML

<?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/mobile_navigation"
    app:startDestination="@id/welcome_screen">

    <fragment
        android:id="@+id/moviesFragment"
        android:name="com.example.movies.ui.movies.MoviesFragment"
        android:label="Home"
        tools:layout="@layout/fragment_movies">
        <action
            android:id="@+id/action_moviesFragment_to_movieDetailsFragment"
            app:destination="@id/movieDetailsFragment"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right" />
        <action
            android:id="@+id/action_homeFragment_to_moviesFilterFragment"
            app:destination="@id/moviesFilterFragment"
            app:enterAnim="@anim/enter_from_top"
            app:exitAnim="@anim/exit_to_bottom" />

    </fragment>
    <fragment
        android:id="@+id/movieDetailsFragment"
        android:name="com.example.movies.ui.move_details.MovieDetailsFragment"
        tools:layout="@layout/fragment_movie_details" >
        <argument
            android:name="movieId"
            app:argType="integer"/>
        <argument
            android:name="showSavedIcon"
            app:argType="boolean"/>
        <action
            android:id="@+id/action_movieDetailsFragment_self"
            app:destination="@id/movieDetailsFragment"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right" />
    </fragment>
    <fragment
        android:id="@+id/saved_movies"
        android:name="com.example.movies.ui.saved_movie.SavedMovieFragment"
        android:label="Watch list"
        tools:layout="@layout/fragment_saved_movie">
        <action
            android:id="@+id/action_saved_movies_to_movieDetailsFragment"
            app:destination="@id/movieDetailsFragment"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right" />
    </fragment>
    <fragment
        android:id="@+id/nav_login_fragment"
        android:name="com.example.movies.ui.login.LoginFragment"
        android:label="fragment_login"
        tools:layout="@layout/fragment_login">
        <action
            android:id="@+id/action_nav_login_fragment_to_homeFragment"
            app:destination="@id/moviesFragment"
            app:popUpTo="@id/nav_login_fragment"
            app:popUpToInclusive="true"/>
    </fragment>
    <fragment
        android:id="@+id/settings"
        android:name="com.example.movies.ui.settings.SettingsFragment"
        android:label="Settings">
        <action
            android:id="@+id/action_settings_to_nav_login_fragment"
            app:destination="@id/nav_login_fragment"
            app:popUpTo="@id/moviesFragment"
            app:popUpToInclusive="true"/>
    </fragment>
    <fragment
        android:id="@+id/welcome_screen"
        android:name="com.example.movies.ui.welcome_screen.WelcomeScreenFragment"
        android:label="fragment_welcome_screen"
        tools:layout="@layout/fragment_welcome_screen">
        <action
            android:id="@+id/action_welcomeScreenFragment_to_nav_login_fragment"
            app:destination="@id/nav_login_fragment"
            app:popUpTo="@id/welcome_screen"
            app:popUpToInclusive="true" />
        <action
            android:id="@+id/action_welcome_screen_to_homeFragment"
            app:destination="@id/homeFragment"
            app:popUpTo="@id/welcome_screen"
            app:popUpToInclusive="true"/>
    </fragment>
    <fragment
        android:id="@+id/moviesFilterFragment"
        android:name="com.example.movies.ui.movie_filter.MoviesFilterFragment"
        tools:layout="@layout/fragment_movies_filter">
        <action
            android:id="@+id/action_moviesFilterFragment_to_homeFragment"
            app:destination="@id/moviesFragment"
            app:popUpTo="@id/moviesFragment"
            app:popUpToInclusive="true" />
    </fragment>
    <fragment
        android:id="@+id/homeFragment"
        android:name="com.example.movies.ui.home.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@+id/action_homeFragment_to_moviesFragment"
            app:destination="@id/moviesFragment" />
        <action
            android:id="@+id/action_homeFragment_to_movieDetailsFragment"
            app:destination="@id/movieDetailsFragment"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right" />
    </fragment>
    <fragment
        android:id="@+id/explore_fragment"
        android:name="com.example.movies.ui.explore.ExploreFragment"
        android:label="Explore"
        tools:layout="@layout/fragment_explore">
        <action
            android:id="@+id/action_exploreFragment_to_moviesFragment"
            app:destination="@id/moviesFragment" />
    </fragment>


</navigation>

This is XML of ExploreFragment()


<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"
    android:orientation="vertical"
    tools:context=".ui.explore.ExploreFragment">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/home_page_toolbar_color"
        android:theme="@style/ToolBarStyle"
        android:elevation="4dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.cardview.widget.CardView
        android:id="@+id/card_view_search"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="15dp"
        app:cardCornerRadius="32dp"
        app:cardElevation="12dp"
        app:layout_constraintTop_toBottomOf="@id/toolbar">

        <androidx.appcompat.widget.SearchView
            android:id="@+id/search_view"
            android:layout_width="match_parent"
            android:layout_height="34dp"
            android:background="@drawable/background_search_view"
            app:iconifiedByDefault="false"
            app:queryHint="@string/search_view_hint"
            tools:ignore="RtlSymmetry" />
    </androidx.cardview.widget.CardView>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container_explore"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="15dp"
        android:name="com.example.movies.ui.movie_categories.MovieCategoriesFragment"
        app:layout_constraintTop_toBottomOf="@id/card_view_search"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文