#android #kotlin #navigation
Вопрос:
Я использую 3 фрагмента с 1 активностью для функций профиля пользователя. Я использую навигацию для перехода к фрагментам:
Проблема в том, что когда я перехожу из фрагмента профиля в фрагмент editProfileFragment, изменяю данные пользователя, а затем возвращаюсь к фрагменту профиля с помощью действия навигации, я не могу снова перейти к фрагменту editProfileFragment из фрагмента профиля. Я получил эту ошибку:
Navigation action/destination xxx:id/action_profileFragment_to_editProfileFragment cannot be found from the current destination Destination(xxx:id/editProfileFragment)
Я пытаюсь использовать архитектуру MVVM, поэтому моя навигация выглядит следующим образом — во фрагменте я наблюдаю живые данные:
navController = Navigation.findNavController(view)
viewModel.navigateTo.observe(viewLifecycleOwner, EventObserver {
navController.navigate(it)
})
Модель просмотра «Навигация»:
private val _navigateTo = MutableLiveData<Event<Int>>()
val navigateTo: LiveData<Event<Int>> = _navigateTo
и методы навигации:
fun goBackToProfile(){
_navigateTo.value = Event(R.id.action_editProfileFragment_to_profileFragment)
}
fun editProfileButtonClick() {
_navigateTo.value = Event(R.id.action_profileFragment_to_editProfileFragment)
}
Я также использую класс оболочки событий Хосе Альсеррека:
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)
}
}
}
Я не знаю, возникает ли ошибка из-за оболочки события или я делаю что-то не так с навигацией. Я буду признателен за любые советы.
ИЗМЕНИТЬ: 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>
Комментарии:
1. Можете ли вы поделиться своим кодом
navigation.xml
?2. Код в отредактированном вопросе
Ответ №1:
Мне кажется, что ты идешь не в ту сторону.
Во-первых
Вы движетесь от ProfileFragment
туда EditProfileFragment
. Затем вы переходите от EditProfileFragment
действия к ProfileFragment
действию, чей идентификатор R.id.action_profileFragment_to_editProfileFragment
.
Это действие , которое, как я вижу, вы определяете из Фрагмента ProfileFragment
, а не EditFragment
.
Убедитесь, что ваши navigateTo
данные в EditProfileFragment
идентификаторе триггера R.id.action_editProfileFragment_to_profileFragment
указаны, когда вы хотите открыть ProfileFragment
EditProfileFragment
.
Во-вторых
Когда вы вернетесь EditProfileFragment
, не звоните navController.navigate()
, так как это сохранит ваш текущий фрагмент в фоновом режиме и переместит ваш целевой фрагмент в фоновый режим. Если вы хотите вернуться, не сохраняя свой текущий фрагмент в резерве, позвоните navController.popBackStack()
.
Комментарии:
1. Я вижу проблему, теперь она работает, спасибо, что уделили мне время
Ответ №2:
Ошибка очень ясна, нет action_profileFragment_to_editProfileFragment
определенного включения editProfileFragment
. если вы посмотрите на свой xml-файл навигации, вы увидите, что action_profileFragment_to_editProfileFragment
он определен для ProfileFragment
.
Но вы пытаетесь использовать это действие навигации , из EditProfileFragment
-за которого возникает ошибка. поэтому либо обновите навигацию, чтобы включить это действие EditProfileFragment
, либо используйте какое-то действие, для которого оно уже определено EditProfileFragment
.