导航到片段时应用程序崩溃
Application crash when navigating to fragment
我正在使用 3 个片段,其中 1 个 activity 用于用户个人资料功能。我使用导航移动到片段:
问题是当我从 profileFragment 转到 editProfileFragment、更改用户数据然后通过导航操作返回到 profileFragment 时,我无法从 profileFragment 再次到达 editProfileFragment。我收到此错误:
Navigation action/destination xxx:id/action_profileFragment_to_editProfileFragment cannot be found from the current destination Destination(xxx:id/editProfileFragment)
我正在尝试使用 MVVM 架构,所以我的导航是这样的 - 在片段中我观察到 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
和导航方法:
fun goBackToProfile(){
_navigateTo.value = Event(R.id.action_editProfileFragment_to_profileFragment)
}
fun editProfileButtonClick() {
_navigateTo.value = Event(R.id.action_profileFragment_to_editProfileFragment)
}
我还使用 Jose Alcerreca 的事件包装器 class:
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>
我觉得你走错了路。
首先
您正在从 ProfileFragment
移动到 EditProfileFragment
。然后,您通过 ID 为 R.id.action_profileFragment_to_editProfileFragment
.
的操作从 EditProfileFragment
移动到 ProfileFragment
我看到你从 Fragment ProfileFragment
定义的那个动作,而不是 EditFragment
。
当您想从 EditProfileFragment
.
打开 ProfileFragment
时,请确保 EditProfileFragment
触发器 ID 中的 LiveData navigateTo
是 R.id.action_editProfileFragment_to_profileFragment
其次
当您从 EditProfileFragment
return 时,不要调用 navController.navigate()
因为它会将您当前的片段保留在后台堆栈中并将您的目标片段推入后台堆栈。如果您想返回而不将当前片段保留在后台堆栈中,请调用 navController.popBackStack()
.
错误很明显,editProfileFragment
上没有定义action_profileFragment_to_editProfileFragment
。如果您查看导航 xml,您可以看到 action_profileFragment_to_editProfileFragment
是为 ProfileFragment
定义的。
但是您正在尝试使用来自 EditProfileFragment
的导航操作,这导致了错误。因此,要么更新您的导航以包含 EditProfileFragment
的此操作,要么使用一些已经为 EditProfileFragment
.
定义的操作
我正在使用 3 个片段,其中 1 个 activity 用于用户个人资料功能。我使用导航移动到片段:
问题是当我从 profileFragment 转到 editProfileFragment、更改用户数据然后通过导航操作返回到 profileFragment 时,我无法从 profileFragment 再次到达 editProfileFragment。我收到此错误:
Navigation action/destination xxx:id/action_profileFragment_to_editProfileFragment cannot be found from the current destination Destination(xxx:id/editProfileFragment)
我正在尝试使用 MVVM 架构,所以我的导航是这样的 - 在片段中我观察到 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
和导航方法:
fun goBackToProfile(){
_navigateTo.value = Event(R.id.action_editProfileFragment_to_profileFragment)
}
fun editProfileButtonClick() {
_navigateTo.value = Event(R.id.action_profileFragment_to_editProfileFragment)
}
我还使用 Jose Alcerreca 的事件包装器 class:
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>
我觉得你走错了路。
首先
您正在从 ProfileFragment
移动到 EditProfileFragment
。然后,您通过 ID 为 R.id.action_profileFragment_to_editProfileFragment
.
EditProfileFragment
移动到 ProfileFragment
我看到你从 Fragment ProfileFragment
定义的那个动作,而不是 EditFragment
。
当您想从 EditProfileFragment
.
ProfileFragment
时,请确保 EditProfileFragment
触发器 ID 中的 LiveData navigateTo
是 R.id.action_editProfileFragment_to_profileFragment
其次
当您从 EditProfileFragment
return 时,不要调用 navController.navigate()
因为它会将您当前的片段保留在后台堆栈中并将您的目标片段推入后台堆栈。如果您想返回而不将当前片段保留在后台堆栈中,请调用 navController.popBackStack()
.
错误很明显,editProfileFragment
上没有定义action_profileFragment_to_editProfileFragment
。如果您查看导航 xml,您可以看到 action_profileFragment_to_editProfileFragment
是为 ProfileFragment
定义的。
但是您正在尝试使用来自 EditProfileFragment
的导航操作,这导致了错误。因此,要么更新您的导航以包含 EditProfileFragment
的此操作,要么使用一些已经为 EditProfileFragment
.