问题
I have 3 bottom navigation tabs called Home, Dashboard, Profile
.
- In
Home
, I haveFragment1
andFragment2
, - In
Dashboard
, I haveFragment3
andFragment4
- And in
Profile
, I haveMyProfile
andEditProfile
.
Now, in Fragment2
, a button changeAvatar
can open EditProfile
in stack Profile
. 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?
回答1:
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"))
回答2:
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" />
回答3:
What you are looking for is known as global action.
Given you have the following nav_graph
structure:
<?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
:
<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.
fun navigateToChangeAvatar() {
changeAvatar.setOnClickListener { view ->
view.findNavController().navigate(R.id.navigateToEditProfile)
}
}
回答4:
To navigate from Home > Fragment2 to Profile > EditProfile you can pass an id by edit type using Navigation
.
Fragment2.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
}
}
}
EditProfileVM.kt
val editTypeId = MutableLiveData<String>()
fun setEditTypeId(id: editTypeId ) {...}
res/navigation/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
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
GL
来源:https://stackoverflow.com/questions/61498100/how-to-switch-to-other-fragment-in-different-back-stack-using-navigation-compone