繁体   English   中英

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

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

我有 3 个底部导航选项卡,分别称为Home, Dashboard, Profile

  • Home ,我有Fragment1Fragment2
  • Dashboard中,我有Fragment3Fragment4
  • Profile中,我有MyProfileEditProfile

现在,在Fragment2中,一个按钮changeAvatar可以打开堆栈Profile中的EditProfile 因为EditProfile应该在选项卡Profile中,所以如果我不想将EditProfile包含到HomenavGraph中,我该如何实现这种行为?

您正在寻找的是全球行动

鉴于您具有以下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>

注意actionProfile中的action部分:

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

以上是您正在寻找的实际全局操作

因此,要将流程透视,您将执行以下操作以从Fragment2 changeAvatar 按钮导航。

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

尝试使用深层链接

导航图。

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

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

在片段中。

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

您必须像这样声明您的操作才能从您的后台堆栈中获取一个片段

<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" />

要从Home > Fragment2导航到Profile > EditProfile ,您可以使用Navigation按编辑类型传递 id。

片段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

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
         }
    }
}

编辑配置文件VM.kt

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

资源/导航/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>

编辑类型.kt

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

注意:导航的 arguments 不能是 Enum 类型

总帐

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM