Kotlin - 导航组件 - 无法从当前目的地找到导航 action/destination
Kotlin - Navigation Components - Navigation action/destination cannot be found from the current destination
问题
java.lang.IllegalArgumentException: Navigation action/destination xxxx/action_scanFragment_to_addVehicleFragment cannot be found from the current destination xxxx/addVehicleFragment
我做的时候出现错误
findNavController().navigate(R.id.action_scanFragment_to_addVehicleFragment)
在扫描片段中。这意味着当前目的地是 addVehicleFragment,但它应该是 scanFragment。
我对如何解决这个问题一无所知。请参阅我之前的问题以了解一些故障排除以及 scanFragment 中真正发生的事情:
Kotlin - fragment lifecycle navigation issues; why does child fragment become current destination?
我怀疑我的导航设置有误,但我找不到解决办法。
我在下面发布我的整个导航 implementation/code。
我的nav_graph设计:
我的nav_graphXML:
<?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/nav_graph"
app:startDestination="@id/mainFragment">
<fragment
android:id="@+id/scanFragment"
android:name="xxxx.ui.scan.ScanFragment"
android:label="@string/tab_bar_first_item_title"
tools:layout="@layout/fragment_scan" >
<action
android:id="@+id/action_scanFragment_to_addVehicleFragment"
app:destination="@id/addVehicleFragment"
app:enterAnim="@anim/from_left"
app:exitAnim="@anim/to_left" />
</fragment>
<fragment
android:id="@+id/addVehicleFragment"
android:name="xxxx.ui.scan.AddVehicleFragment"
android:label="@string/add_vehicle_fragment_title_string"
tools:layout="@layout/fragment_add_vehicle">
<action
android:id="@+id/action_addVehicleFragment_to_scanFragment"
app:destination="@id/scanFragment" />
</fragment>
<fragment
android:id="@+id/mainFragment"
android:name="xxxx.ui.main.MainFragment"
android:label="@string/tab_bar_second_item_title"
tools:layout="@layout/fragment_main" />
<fragment
android:id="@+id/profileFragment"
android:name="xxxx.ui.profile.ProfileFragment"
android:label="@string/tab_bar_third_item_title"
tools:layout="@layout/fragment_profile">
<action
android:id="@+id/actionMyVehicles"
app:destination="@id/myVehiclesFragment"
app:enterAnim="@anim/from_right"
app:exitAnim="@anim/to_left" />
<action
android:id="@+id/actionMyRooms"
app:destination="@+id/myRoomsFragment"
app:enterAnim="@anim/from_right"
app:exitAnim="@anim/to_left" />
</fragment>
<fragment
android:id="@+id/myVehiclesFragment"
android:name="xxxx.ui.profile.MyVehiclesFragment"
android:label="fragment_my_vehicles"
tools:layout="@layout/fragment_my_vehicles" >
<action
android:id="@+id/action_myVehiclesFragment_to_profileFragment"
app:destination="@id/profileFragment"
app:enterAnim="@anim/from_left"
app:exitAnim="@anim/to_right" />
</fragment>
<fragment
android:id="@+id/myRoomsFragment"
android:name="xxxx.ui.profile.MyRoomsFragment"
android:label="fragment_my_rooms"
tools:layout="@layout/fragment_my_rooms" >
<action
android:id="@+id/action_myRoomsFragment_to_profileFragment"
app:destination="@id/profileFragment"
app:enterAnim="@anim/from_left"
app:exitAnim="@anim/to_right" />
</fragment>
</navigation>
我的主Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_activity_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/light_gray"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/tabBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph">
</androidx.fragment.app.FragmentContainerView>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/tabBar"
android:layout_width="match_parent"
android:layout_height="58dp"
android:layout_alignParentBottom="true"
app:elevation="2dp"
app:itemBackground="@color/light_gray"
app:itemIconSize="30dp"
app:itemIconTint="@color/tab_bar_icon_tint_color"
app:labelVisibilityMode="unlabeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/tab_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
主要Activity:
class MainActivity : AppCompatActivity() {
private lateinit var viewBinding: ActivityMainBinding
private lateinit var tabBar: BottomNavigationView
private lateinit var navHostFragment: NavHostFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
println("MainActivity || onCreate ||")
// Initialize viewBinding object
viewBinding = ActivityMainBinding.inflate(layoutInflater)
// Hide the default navigation bar; we implement our own
supportActionBar!!.hide()
viewBinding.loadingPageLayout.visibility = View.GONE
setContentView(viewBinding.root)
setupBottomBarNavigation()
}
private fun setupBottomBarNavigation() {
tabBar = viewBinding.tabBar
navHostFragment = supportFragmentManager.findFragmentById(R.id.navHostFragment) as NavHostFragment
val navigationController = navHostFragment.navController
val appBarConfiguration = AppBarConfiguration(setOf(R.id.scanFragment, R.id.mainFragment, R.id.profileFragment))
setupActionBarWithNavController(navigationController, appBarConfiguration)
tabBar.setupWithNavController(navigationController)
val navHost = supportFragmentManager.currentNavigationFragment
println("Current navigation fragment: $navHost")
}
override fun onSupportNavigateUp() =
Navigation.findNavController(this, R.id.navHostFragment).navigateUp()
请帮助一个绝望的家伙!
问题不在导航组件中,而是 - 我认为 - 在我的 ImageAnalyzer 中。原来我不小心允许多次调用 findNavController.navigate()。既然我解决了这个问题,我的导航问题就消失了。
如果有人因为多次点击屏幕而遇到同样的问题。导航前先检查当前目的地即可解决
例如
片段 A、B 和 C
在点击片段 A 中导航到 C 的按钮时从 A 导航到 B 在某些情况下可能会导致崩溃
为此,您应该先检查当前目的地,如下所示:
if(findNavController().currentDestination?.id==R.id.AFragment)
findNavController().navigate(
AFragmentDirections.actionAFragmentToCFragment()
)
问题
java.lang.IllegalArgumentException: Navigation action/destination xxxx/action_scanFragment_to_addVehicleFragment cannot be found from the current destination xxxx/addVehicleFragment
我做的时候出现错误
findNavController().navigate(R.id.action_scanFragment_to_addVehicleFragment)
在扫描片段中。这意味着当前目的地是 addVehicleFragment,但它应该是 scanFragment。
我对如何解决这个问题一无所知。请参阅我之前的问题以了解一些故障排除以及 scanFragment 中真正发生的事情: Kotlin - fragment lifecycle navigation issues; why does child fragment become current destination?
我怀疑我的导航设置有误,但我找不到解决办法。
我在下面发布我的整个导航 implementation/code。
我的nav_graph设计:
我的nav_graphXML:
<?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/nav_graph"
app:startDestination="@id/mainFragment">
<fragment
android:id="@+id/scanFragment"
android:name="xxxx.ui.scan.ScanFragment"
android:label="@string/tab_bar_first_item_title"
tools:layout="@layout/fragment_scan" >
<action
android:id="@+id/action_scanFragment_to_addVehicleFragment"
app:destination="@id/addVehicleFragment"
app:enterAnim="@anim/from_left"
app:exitAnim="@anim/to_left" />
</fragment>
<fragment
android:id="@+id/addVehicleFragment"
android:name="xxxx.ui.scan.AddVehicleFragment"
android:label="@string/add_vehicle_fragment_title_string"
tools:layout="@layout/fragment_add_vehicle">
<action
android:id="@+id/action_addVehicleFragment_to_scanFragment"
app:destination="@id/scanFragment" />
</fragment>
<fragment
android:id="@+id/mainFragment"
android:name="xxxx.ui.main.MainFragment"
android:label="@string/tab_bar_second_item_title"
tools:layout="@layout/fragment_main" />
<fragment
android:id="@+id/profileFragment"
android:name="xxxx.ui.profile.ProfileFragment"
android:label="@string/tab_bar_third_item_title"
tools:layout="@layout/fragment_profile">
<action
android:id="@+id/actionMyVehicles"
app:destination="@id/myVehiclesFragment"
app:enterAnim="@anim/from_right"
app:exitAnim="@anim/to_left" />
<action
android:id="@+id/actionMyRooms"
app:destination="@+id/myRoomsFragment"
app:enterAnim="@anim/from_right"
app:exitAnim="@anim/to_left" />
</fragment>
<fragment
android:id="@+id/myVehiclesFragment"
android:name="xxxx.ui.profile.MyVehiclesFragment"
android:label="fragment_my_vehicles"
tools:layout="@layout/fragment_my_vehicles" >
<action
android:id="@+id/action_myVehiclesFragment_to_profileFragment"
app:destination="@id/profileFragment"
app:enterAnim="@anim/from_left"
app:exitAnim="@anim/to_right" />
</fragment>
<fragment
android:id="@+id/myRoomsFragment"
android:name="xxxx.ui.profile.MyRoomsFragment"
android:label="fragment_my_rooms"
tools:layout="@layout/fragment_my_rooms" >
<action
android:id="@+id/action_myRoomsFragment_to_profileFragment"
app:destination="@id/profileFragment"
app:enterAnim="@anim/from_left"
app:exitAnim="@anim/to_right" />
</fragment>
</navigation>
我的主Activity XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_activity_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/light_gray"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/tabBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph">
</androidx.fragment.app.FragmentContainerView>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/tabBar"
android:layout_width="match_parent"
android:layout_height="58dp"
android:layout_alignParentBottom="true"
app:elevation="2dp"
app:itemBackground="@color/light_gray"
app:itemIconSize="30dp"
app:itemIconTint="@color/tab_bar_icon_tint_color"
app:labelVisibilityMode="unlabeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/tab_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
主要Activity:
class MainActivity : AppCompatActivity() {
private lateinit var viewBinding: ActivityMainBinding
private lateinit var tabBar: BottomNavigationView
private lateinit var navHostFragment: NavHostFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
println("MainActivity || onCreate ||")
// Initialize viewBinding object
viewBinding = ActivityMainBinding.inflate(layoutInflater)
// Hide the default navigation bar; we implement our own
supportActionBar!!.hide()
viewBinding.loadingPageLayout.visibility = View.GONE
setContentView(viewBinding.root)
setupBottomBarNavigation()
}
private fun setupBottomBarNavigation() {
tabBar = viewBinding.tabBar
navHostFragment = supportFragmentManager.findFragmentById(R.id.navHostFragment) as NavHostFragment
val navigationController = navHostFragment.navController
val appBarConfiguration = AppBarConfiguration(setOf(R.id.scanFragment, R.id.mainFragment, R.id.profileFragment))
setupActionBarWithNavController(navigationController, appBarConfiguration)
tabBar.setupWithNavController(navigationController)
val navHost = supportFragmentManager.currentNavigationFragment
println("Current navigation fragment: $navHost")
}
override fun onSupportNavigateUp() =
Navigation.findNavController(this, R.id.navHostFragment).navigateUp()
请帮助一个绝望的家伙!
问题不在导航组件中,而是 - 我认为 - 在我的 ImageAnalyzer 中。原来我不小心允许多次调用 findNavController.navigate()。既然我解决了这个问题,我的导航问题就消失了。
如果有人因为多次点击屏幕而遇到同样的问题。导航前先检查当前目的地即可解决
例如
片段 A、B 和 C
在点击片段 A 中导航到 C 的按钮时从 A 导航到 B 在某些情况下可能会导致崩溃
为此,您应该先检查当前目的地,如下所示:
if(findNavController().currentDestination?.id==R.id.AFragment)
findNavController().navigate(
AFragmentDirections.actionAFragmentToCFragment()
)