Kotlin导航无法找到碎片

mrfwxfqh  于 2023-01-26  发布在  Kotlin
关注(0)|答案(3)|浏览(138)

我有多个活动的多个导航图,但通过navController导航到片段时总是出现问题。它总是返回这样的错误无法从当前目的地找到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

我尝试过safeargs的各种解决方案,比如使用Directionsnavigate by ids等,结果都是同样的错误。
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,其中向用户显示所有订单的列表
1.由于我面临着从该列表项中获取详细信息片段的相同问题,我所做的是在此活动中创建名为OrdersActivity的新活动,我通过OrderDetailFragment(活动的主要片段)获取订单详细信息
1.现在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()
    }
}
shyt4zoc

shyt4zoc1#

您正在使用NavHostFragment,您根本不应该使用任何FragmentTransaction-您正在添加NavHostFragment之外的OrderDetailFragment的第二个示例。
OrdersActivity中删除所有这些代码:

class OrdersActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_orders)
    }
}
unguejic

unguejic2#

您需要将<action移出<fragment,它应该是<navigation标记的子标记。

oyxsuwqo

oyxsuwqo3#

我把<argument>元素作为<fragment>的子元素,而不是<action>的子元素,然后立即通过navArgs()使用ClassNameArgs。

<fragment
    android:id="@+id/SecondFragment"
    android:name="com.example.easybrowsing.SecondFragment"
    android:label="@string/second_fragment_label"
    tools:layout="@layout/fragment_second">

    <action
        android:id="@+id/action_SecondFragment_to_FirstFragment"
        app:destination="@id/FirstFragment" />
    <argument
        android:name="website"
        app:argType="com.example.easybrowsing.Website" />
</fragment>

相关问题