Reputation: 41
I am using 3 fragments with 1 activity for user profile features. I use navigation to move to fragments:
The problem is when I go from profileFragment to editProfileFragment, change user's data and then go back to profileFragment by navigation action, I cannot reach editProfileFragment again from profileFragment. I got this error:
Navigation action/destination xxx:id/action_profileFragment_to_editProfileFragment cannot be found from the current destination Destination(xxx:id/editProfileFragment)
I am trying to use MVVM architecture so my navigation goes like this - in fragment I observe LiveData:
navController = Navigation.findNavController(view)
viewModel.navigateTo.observe(viewLifecycleOwner, EventObserver {
navController.navigate(it)
})
viewModel 'navigateTo':
private val _navigateTo = MutableLiveData<Event<Int>>()
val navigateTo: LiveData<Event<Int>> = _navigateTo
and the navigation methods:
fun goBackToProfile(){
_navigateTo.value = Event(R.id.action_editProfileFragment_to_profileFragment)
}
fun editProfileButtonClick() {
_navigateTo.value = Event(R.id.action_profileFragment_to_editProfileFragment)
}
I also use Event wrapper class by Jose Alcerreca:
open class Event<out T>(private val content: T) {
var hasBeenHandled = false
private set // Allow external read but not write
/**
* Returns the content and prevents its use again.
*/
fun getContentIfNotHandled(): T? {
return if (hasBeenHandled) {
null
} else {
hasBeenHandled = true
content
}
}
/**
* Returns the content, even if it's already been handled.
*/
fun peekContent(): T = content
}
class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<Event<T>> {
override fun onChanged(event: Event<T>?) {
event?.getContentIfNotHandled()?.let {
onEventUnhandledContent(it)
}
}
}
I don't know if error occurs because of Event wrapper or I do something wrong with navigation. I will appreciate any advices.
EDIT: 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/main_nav_graph"
app:startDestination="@id/homeFragment">
<fragment
android:id="@+id/homeFragment"
android:name="xxx.mainPackage.views.HomeFragment"
android:label="fragment_home"
tools:layout="@layout/fragment_home" />
<fragment
android:id="@+id/profileFragment"
android:name="xxx.mainPackage.views.ProfileFragment"
android:label="fragment_profile"
tools:layout="@layout/fragment_profile" >
<action
android:id="@+id/action_profileFragment_to_editProfileFragment"
app:destination="@id/editProfileFragment" />
</fragment>
<fragment
android:id="@+id/editProfileFragment"
android:name="xxx.mainPackage.views.EditProfileFragment"
android:label="fragment_edit_profile"
tools:layout="@layout/fragment_edit_profile" >
<action
android:id="@+id/action_editProfileFragment_to_chooseImageFragment"
app:destination="@id/chooseImageFragment" />
<action
android:id="@+id/action_editProfileFragment_to_profileFragment"
app:destination="@id/profileFragment" />
</fragment>
<fragment
android:id="@+id/chooseImageFragment"
android:name="xxx.mainPackage.views.ChooseImageFragment"
android:label="ChooseImageFragment" >
<action
android:id="@+id/action_chooseImageFragment_to_editProfileFragment"
app:destination="@id/editProfileFragment" />
</fragment>
</navigation>
Upvotes: 0
Views: 2825
Reputation: 8315
Error is very clear, there is no action_profileFragment_to_editProfileFragment
defined on editProfileFragment
. if you look at your navigation xml, you can see that action_profileFragment_to_editProfileFragment
is defined for ProfileFragment
.
But you are trying to use this navigation action from EditProfileFragment
, which causes the error. so either update your navigation to include this action for EditProfileFragment
or use some action which is already defined for EditProfileFragment
.
Upvotes: 1
Reputation: 2421
It looks to me like you're navigating the wrong way.
Firstly
You are moving from ProfileFragment
to EditProfileFragment
. Then you move from EditProfileFragment
to ProfileFragment
via action whose id is R.id.action_profileFragment_to_editProfileFragment
.
That action I see you define from Fragment ProfileFragment
, not EditFragment
.
Make sure your LiveData navigateTo
in EditProfileFragment
trigger id is R.id.action_editProfileFragment_to_profileFragment
when you want to open ProfileFragment
from EditProfileFragment
.
Secondly
When you return from EditProfileFragment
, don't call navController.navigate()
as it will keep your current fragment in the backstack and push your target fragment to the backstack. If you want to go back without keeping your current fragment in the backstack, call navController.popBackStack()
.
Upvotes: 1