【问题标题】:Application crash when navigating to fragment导航到片段时应用程序崩溃
【发布时间】:2021-08-26 11:26:34
【问题描述】:

我将 3 个片段和 1 个活动用于用户配置文件功能。我使用导航移动到片段:

问题是当我从 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 的 Event wrapper 类:

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

我不知道是否由于事件包装器而发生错误,或者我在导航方面做错了什么。我会很感激任何建议。

编辑: 导航.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>

【问题讨论】:

  • 你能分享你的navigation.xml的代码吗?
  • 已编辑问题中的代码

标签: android kotlin navigation


【解决方案1】:

在我看来,您的导航方向错误。

首先

您正在从ProfileFragment 移动到EditProfileFragment。然后通过 id 为 R.id.action_profileFragment_to_editProfileFragment 的操作从 EditProfileFragment 移动到 ProfileFragment

我看到你从 Fragment ProfileFragment 定义的那个动作,而不是 EditFragment

当您想从EditProfileFragment 打开ProfileFragment 时,确保EditProfileFragment 触发器ID 中的LiveData navigateToR.id.action_editProfileFragment_to_profileFragment

其次

当您从EditProfileFragment 返回时,不要调用navController.navigate(),因为它会将您当前的片段保留在后台并将您的目标片段推送到后台。如果您想返回而不将当前片段保留在后台堆栈中,请致电navController.popBackStack()

【讨论】:

  • 我看到了问题,现在可以了,感谢您的宝贵时间
【解决方案2】:

错误很清楚,editProfileFragment 上没有定义action_profileFragment_to_editProfileFragment。如果您查看导航 xml,您可以看到 action_profileFragment_to_editProfileFragment 是为 ProfileFragment 定义的。

但您尝试使用来自EditProfileFragment 的导航操作,这会导致错误。因此,要么更新您的导航以包含 EditProfileFragment 的此操作,要么使用已为 EditProfileFragment 定义的某些操作。

【讨论】:

    猜你喜欢
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    • 2018-08-26
    相关资源
    最近更新 更多