简体   繁体   English

如何使用导航组件切换到不同后台堆栈中的其他片段?

[英]How to switch to other fragment in different back stack using Navigation Component?

I have 3 bottom navigation tabs called Home, Dashboard, Profile .我有 3 个底部导航选项卡,分别称为Home, Dashboard, Profile

  • In Home , I have Fragment1 and Fragment2 ,Home ,我有Fragment1Fragment2
  • In Dashboard , I have Fragment3 and Fragment4Dashboard中,我有Fragment3Fragment4
  • And in Profile , I have MyProfile and EditProfile .Profile中,我有MyProfileEditProfile

Now, in Fragment2 , a button changeAvatar can open EditProfile in stack Profile .现在,在Fragment2中,一个按钮changeAvatar可以打开堆栈Profile中的EditProfile Because EditProfile should be in tab Profile , so if I don't want to include EditProfile into navGraph of Home , how can I achieve that behavior?因为EditProfile应该在选项卡Profile中,所以如果我不想将EditProfile包含到HomenavGraph中,我该如何实现这种行为?

What you are looking for is known as global action .您正在寻找的是全球行动

Given you have the following nav_graph structure:鉴于您具有以下nav_graph结构:

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

    <navigation
            android:id="@+id/actionHome"
            android:label="Home"
            app:startDestination="@id/fragment1">
        <fragment
                android:id="@+id/fragment1"
                android:name="com.example.app.Fragment1"
                android:label="Home Fragment 1"
                tools:layout="@layout/fragment_1" />
        <fragment
                android:id="@+id/fragment2"
                android:name="com.example.app.Fragment2"
                android:label="Home Fragment 2"
                tools:layout="@layout/fragment_2" />

    </navigation>

    <navigation
            android:id="@+id/actionDashboard"
            android:label="Dashboard"
            app:startDestination="@id/fragment3">
        <fragment
                android:id="@+id/fragment3"
                android:name="com.example.app.Fragment3"
                android:label="Dashboard Fragment 3"
                tools:layout="@layout/fragment_3" />
        <fragment
                android:id="@+id/fragment4"
                android:name="com.example.app.Fragment4"
                android:label="Dashboard Fragment 4"
                tools:layout="@layout/fragment_4" />

    </navigation>

    <navigation
            android:id="@+id/actionProfile"
            android:label="Profile"
            app:startDestination="@id/myProfileFragment">
        <fragment
                android:id="@+id/myProfileFragment"
                android:name="com.example.app.MyProfileFragment"
                android:label="My Profile"
                tools:layout="@layout/fragment_my_profile"/>

        <fragment
                android:id="@+id/editProfileFragment"
                android:name="com.example.app.EditProfileFragment"
                android:label="Edit Profile"
                tools:layout="@layout/fragment_edit_profile"/>

        <action
                android:id="@+id/navigateToEditProfile"
                app:destination="@id/editProfileFragment" />
    </navigation>
</navigation>

Note the action section within actionProfile :注意actionProfile中的action部分:

<action
        android:id="@+id/navigateToEditProfile"
        app:destination="@id/editProfileFragment" />

The above is the actual global action that you are looking for.以上是您正在寻找的实际全局操作

So to put the flow into perspective you would do the following to navigate from Fragment2 changeAvatar button.因此,要将流程透视,您将执行以下操作以从Fragment2 changeAvatar 按钮导航。

fun navigateToChangeAvatar() {
    changeAvatar.setOnClickListener { view ->
        view.findNavController().navigate(R.id.navigateToEditProfile)
    }
}

try with the deep link尝试使用深层链接

Navigation graph.导航图。

<navigation
 ...>
    <fragment
        android:id="@+id/editProfileFragment"
        >

        ...
        <deepLink
            android:id="@+id/deepLink"
            app:uri="yourapp://edit/prfile" />
        ...
    </fragment>
</navigation>

In Fragment.在片段中。

findNavController().navigate(Uri.parse("yourapp://edit/prfile"))

You have to declare your action like this for getting a fragment from your back stack您必须像这样声明您的操作才能从您的后台堆栈中获取一个片段

<action
    android:id="@+id/yourActionName"
                 app:destination="@id/editProfileFragment" />
                 app:enterAnim="@anim/slide_in_right"
                 app:exitAnim="@anim/slide_out_left"
                 app:popEnterAnim="@anim/slide_in_left"
                 app:popExitAnim="@anim/slide_out_right"
                 app:popUpTo="@+id/editProfileFragment" />

To navigate from Home > Fragment2 to Profile > EditProfile you can pass an id by edit type using Navigation .要从Home > Fragment2导航到Profile > EditProfile ,您可以使用Navigation按编辑类型传递 id。

Fragment2.kt片段2.kt

private fun navigateToEditProfileAvatar() {
    buttonEditProfileAvatar.setOnClickListener { button -> 
        Navigation.findNavController(button).navigate(
                R.id.action_global_to_edit_profile,
                RootNavigationDirections.actionGlobalToEditProfile(
                        editType = EditType.EDIT_PROFILE_AVATAR.id
                ).arguments
        )
    }
}

EditProfileFragment.kt EditProfileFragment.kt

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState) 

    ...

    viewModel.setEditTypeId(EditProfileFragmentArgs.fromBundle(arguments ?: Bundle()).editType)

}

private fun bind() {
    when (viewModel.editTypeId) {
         EditType.EDIT_PROFILE.id -> { ... }
         EditType.EDIT_PROFILE_AVATAR.id -> { 
             // here
         }
    }
}

EditProfileVM.kt编辑配置文件VM.kt

val editTypeId = MutableLiveData<String>()
fun setEditTypeId(id: editTypeId ) {...}

res/navigation/root_navigation.xml资源/导航/root_navigation.xml

<action
    android:id="@+id/action_global_to_edit_profile"
    app:destination="@id/edit_profile_fragment" />

<fragment
    android:id="@+id/edit_profile_fragment"
    android:name="EditProfileFragment"
    android:label=" "
    tools:layout="@layout/fragment_edit_profile">

    <argument
        android:name="editType"
        app:argType="string"
        android:defaultValue="@string/edit_profile"
    />

</fragment>

EditType.kt编辑类型.kt

enum class EditType(val id: String) {
    EDIT_PROFILE("EDIT_PROFILE"), EDIT_PROFILE_AVATAR("EDIT_PROFILE_AVATAR");
}

Note : The arguments of a navigation cannot be of type Enum注意:导航的 arguments 不能是 Enum 类型

GL总帐

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 导航组件,检查返回堆栈中是否存在片段 - Navigation component , check if fragment exists in back stack 导航组件:查找片段是否在回栈中 - Navigation Component: Find if a fragment is in the back stack 使用导航组件时如何知道堆栈中的片段数? - How to know the number of fragment that are in stack when using Navigation Component? 如何使用导航组件清除返回堆栈中的每个片段(例如,当 HTTP 401 触发时)并发送到登录片段 - How can I clear every fragments in back stack using Navigation Component (for example when HTTP 401 triggeres) and sent to login fragment 导航 Controller:如何在后栈中插入片段 - Navigation Controller: how to insert a fragment in the back stack 如何使用导航组件导航回上一个片段 - How to navigate back to previous fragment using Navigation component 导航体系结构组件:如何从后堆栈导航片段? - Navigation Architecture Component: How i can navigate a fragment from the back stack? 如何使用 Android Jetpack 的导航组件禁用后退导航并删除 Fragment 上的后退箭头? - How do I disable back navigation and remove the back arrow on a Fragment, using Android Jetpack's Navigation component? 使用导航架构组件时如何与其他片段交互? - How to interact with other fragment when using Navigation architecture component? 如何清除导航组件中的碎片堆栈? - How to clear back stack of Fragments in Navigation Component?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM