Kotlin Navigation 找不到片段
Kotlin Navigation cannot find fragments
我有多个活动的多个导航图,但我总是无法通过 navController 导航到片段。它总是return这样的错误无法从当前目的地Destination
中找到
java.lang.IllegalArgumentException: Navigation action/destination com.my.app:id/action_orderDetailFragment_to_driverMapFragment cannot be found from the current destination Destination(com.my.app:id/driverMapFragment) label=fragment_driver_map class=com.my.app.orders.DriverMapFragment
我已经通过使用 Directions
和 navigate
等尝试了 safeargs 的各种解决方案。它们都以相同的错误结束。处理导航变得令人沮丧
navigation screenshot
Fragment
class OrderDetailFragment : Fragment(), View.OnClickListener {
lateinit var navController: NavController
lateinit var drivermap: Button
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
view.findViewById<Button>(R.id.drivermap).setOnClickListener(this)
}
// other functions....
// here suppose to redirect to "driverMapFragment" from "orderDetailFragment" along with "Order ID"
override fun onClick(v: View?) {
when(v!!.id) {
R.id.drivermap -> {
// (1) Returning Error
val bundle = bundleOf("orderIDArgument" to orderIDArgument)
navController!!.navigate(R.id.action_orderDetailFragment_to_driverMapFragment, bundle)
// (2) Returning Error
// val action = OrderDetailFragmentDirections.actionOrderDetailFragmentToDriverMapFragment(bundle)
// v.findNavController().navigate(action)
}
}
}
}
PS:为了避免不必要的评论,我不得不提到我在 gradles 中确实有 safeargs。
app level gradle
apply plugin: "androidx.navigation.safeargs.kotlin"
project level gradle
dependencies {
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
}
更新 1
更新 2
Structure
- 我有 OrdersFragment,其中向用户显示了所有订单的列表
- 由于我面临着从该列表项中获取详细信息片段的相同问题,我所做的是创建新的 activity 并将其命名为
OrdersActivity
在此 activity 我通过以下方式获取订单详细信息OrderDetailFragment
(activity的主要片段)
- 现在
OrdersActivity
有新片段,我正在尝试显示顺序图(从 OrderDetailFragment
重定向到 driverMapFragment
)
PS:我知道这个结构有点乱(主要是因为我被迫制作了我不想做的 OrdersActivity
,但同样的问题(错误)我这样做。
现在这是我的 activity_orders.xml
<ScrollView
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:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="56dp"
android:fillViewport="true"
tools:context=".orders.OrdersActivity">
// by default it loads `OrderDetailFragment` then its supposed to switch to maps fragment when button is clicked inside `OrderDetailFragment`
<androidx.fragment.app.FragmentContainerView
android:id="@+id/orderFragmentId"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/order_detail" />
</ScrollView>
OrdersActivity.kt
class OrdersActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_orders)
// make sure main fragment loads only once
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
.add(R.id.orderFragmentId, OrderDetailFragment())
.commit()
}
}
private fun navigateTo(fragment: Fragment) {
val transaction = supportFragmentManager
.beginTransaction()
.replace(R.id.orderFragmentId, fragment)
transaction.commit()
}
}
您需要将 <action
移到 <fragment
之外,它应该是 <navigation
标签的子标签。
您正在使用 NavHostFragment
,您根本不应该使用任何 FragmentTransaction
- 您正在添加 NavHostFragment
之外的 OrderDetailFragment
的第二个实例=].
从您的 OrdersActivity
:
中删除所有代码
class OrdersActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_orders)
}
}
我有多个活动的多个导航图,但我总是无法通过 navController 导航到片段。它总是return这样的错误无法从当前目的地Destination
中找到java.lang.IllegalArgumentException: Navigation action/destination com.my.app:id/action_orderDetailFragment_to_driverMapFragment cannot be found from the current destination Destination(com.my.app:id/driverMapFragment) label=fragment_driver_map class=com.my.app.orders.DriverMapFragment
我已经通过使用 Directions
和 navigate
等尝试了 safeargs 的各种解决方案。它们都以相同的错误结束。处理导航变得令人沮丧
navigation screenshot
Fragment
class OrderDetailFragment : Fragment(), View.OnClickListener {
lateinit var navController: NavController
lateinit var drivermap: Button
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
view.findViewById<Button>(R.id.drivermap).setOnClickListener(this)
}
// other functions....
// here suppose to redirect to "driverMapFragment" from "orderDetailFragment" along with "Order ID"
override fun onClick(v: View?) {
when(v!!.id) {
R.id.drivermap -> {
// (1) Returning Error
val bundle = bundleOf("orderIDArgument" to orderIDArgument)
navController!!.navigate(R.id.action_orderDetailFragment_to_driverMapFragment, bundle)
// (2) Returning Error
// val action = OrderDetailFragmentDirections.actionOrderDetailFragmentToDriverMapFragment(bundle)
// v.findNavController().navigate(action)
}
}
}
}
PS:为了避免不必要的评论,我不得不提到我在 gradles 中确实有 safeargs。
app level gradle
apply plugin: "androidx.navigation.safeargs.kotlin"
project level gradle
dependencies {
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
}
更新 1
更新 2
Structure
- 我有 OrdersFragment,其中向用户显示了所有订单的列表
- 由于我面临着从该列表项中获取详细信息片段的相同问题,我所做的是创建新的 activity 并将其命名为
OrdersActivity
在此 activity 我通过以下方式获取订单详细信息OrderDetailFragment
(activity的主要片段) - 现在
OrdersActivity
有新片段,我正在尝试显示顺序图(从OrderDetailFragment
重定向到driverMapFragment
)
PS:我知道这个结构有点乱(主要是因为我被迫制作了我不想做的 OrdersActivity
,但同样的问题(错误)我这样做。
现在这是我的 activity_orders.xml
<ScrollView
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:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="56dp"
android:fillViewport="true"
tools:context=".orders.OrdersActivity">
// by default it loads `OrderDetailFragment` then its supposed to switch to maps fragment when button is clicked inside `OrderDetailFragment`
<androidx.fragment.app.FragmentContainerView
android:id="@+id/orderFragmentId"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/order_detail" />
</ScrollView>
OrdersActivity.kt
class OrdersActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_orders)
// make sure main fragment loads only once
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
.add(R.id.orderFragmentId, OrderDetailFragment())
.commit()
}
}
private fun navigateTo(fragment: Fragment) {
val transaction = supportFragmentManager
.beginTransaction()
.replace(R.id.orderFragmentId, fragment)
transaction.commit()
}
}
您需要将 <action
移到 <fragment
之外,它应该是 <navigation
标签的子标签。
您正在使用 NavHostFragment
,您根本不应该使用任何 FragmentTransaction
- 您正在添加 NavHostFragment
之外的 OrderDetailFragment
的第二个实例=].
从您的 OrdersActivity
:
class OrdersActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_orders)
}
}