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

我已经通过使用 Directionsnavigate 等尝试了 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

  1. 我有 OrdersFragment,其中向用户显示了所有订单的列表
  2. 由于我面临着从该列表项中获取详细信息片段的相同问题,我所做的是创建新的 activity 并将其命名为 OrdersActivity 在此 activity 我通过以下方式获取订单详细信息OrderDetailFragment(activity的主要片段)
  3. 现在 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)
    }
}