首页 > 解决方案 > Android Kotlin 使用 Safe Args Navigation 传递数据返回 null

问题描述

所以在这里我有两个片段,它们应该使用 Safe Args Navigation 将数据从一个传递到另一个。

第一个片段 ( OrderListFragment.kt) 应该将参数传递给第二个片段 ( OrderDetailFragment.kt)。

这是来自的代码片段navigation.xml

<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/navigation"
app:startDestination="@id/loginFragment">

...
...


<action android:id="@+id/toOrderDetailFragment"
    app:destination="@+id/orderDetailFragment">
    <argument
        android:name="orderId"
        app:argType="string" /> <- This is what I want to Pass
</action>

...
...

<fragment
        android:id="@+id/orderListFragment"
        android:name="com.example.switchingandroidappproject.mainFragments.OrderListFragment"
        android:label="OrderListFragment" >
        <action
            android:id="@+id/action_orderListFragment_to_orderDetailFragment"
            app:destination="@id/orderDetailFragment"
            app:enterAnim="@anim/slide_in_left"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_left" >
        </action>
    </fragment>

<fragment
        android:id="@+id/orderDetailFragment"
        android:name="com.example.switchingandroidappproject.mainFragments.OrderDetailFragment"
        android:label="OrderDetailFragment" >
        <argument
            android:name="orderId"
            app:argType="string" />
    </fragment>

  ...
...
...

这是来自OrderListFragment.kt(它是一个看起来像这样的recyclerview )的片段。

OrderListFragment.kt

override fun onItemClicked(order: OutstandingOrderListPOJODataClassDataItem) {
    //Navigate to Detail Fragment

    Log.i("Order", "Clicked Item from order List: ${order.orderId}") <- I use this for debugging

    findNavController().navigate(
        NavigationDirections.toOrderDetailFragment(
            order.orderId
        )
    )
}

我很确定 recyclerview 适配器没有任何问题,因为它Log.i()返回了我单击的项目的值。你可以在这里看到它这里

从上面可以看到,第一行是OrderListFragment.kt我单击项目时的。第二行是OrderDetailFragment.kt值应该传递到的地方。

这是来自的片段OrderDetailFragment.kt

OrderDetailFragment.kt

class OrderDetailFragment : Fragment(), OrderedItemListOnItemClickListener {

private val args = arguments?.let { OrderDetailFragmentArgs.fromBundle(it) }
private val selectedOrderId = args?.orderId

lateinit var adapter: OrderedItemListAdapter
private lateinit var binding: FragmentOrderDetailBinding

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    // Change action bar title
    (activity as AppCompatActivity).supportActionBar?.title = "Order Details"


    // View Binding for this Fragment
    binding = DataBindingUtil.inflate(
        inflater,
        R.layout.fragment_order_detail, container, false
    )

    fetchOrderDetail()
    fetchOrderedItemListData()
    Log.i("Order", "CLicked order ID: $selectedOrderId") <- The second line of the LOg message in the screen shot is from this line.

    //Inflate layout to this activity fragment
    return binding.root
}

    ....
    ....
    ....

仅供参考,我OrderListFragment.kt通过改造从 API 端点获取所有数据,并在数据类中解析它们。:

data class OutstandingOrderListPOJODataClass(

    @field:SerializedName("data")
    val data: List<OutstandingOrderListPOJODataClassDataItem?>? = null,

    @field:SerializedName("error")
    val error: Error? = null
)

data class OutstandingOrderListPOJODataClassDataItem(

    @field:SerializedName("buyer_address")
    @Expose
    val buyerAddress: String,

    @field:SerializedName("total_price")
    @Expose
    val totalPrice: Int,

    @field:SerializedName("buyer_name")
    @Expose
    val buyerName: String,

    @field:SerializedName("status_confirmed_yn")
    @Expose
    val statusConfirmedYn: String? = null,

    @field:SerializedName("order_date")
    @Expose
    val orderDate: String,

    @field:SerializedName("outlet_id")
    @Expose
    val outletId: String? = null,

    @field:SerializedName("nip")
    @Expose
    val nip: String? = null,

    @field:SerializedName("jumlah_product")
    @Expose
    val jumlahProduct: Int? = null,

    @field:SerializedName("last_update")
    @Expose
    val lastUpdate: String? = null,

    @field:SerializedName("phone_number")
    @Expose
    val phoneNumber: String,

    @field:SerializedName("order_running_id")
    @Expose
    val orderRunningId: Int? = null,

    @field:SerializedName("status_tagged_yn")
    @Expose
    val statusTaggedYn: String? = null,

    @field:SerializedName("order_id")
    @Expose
    val orderId: String
)

我错过了什么吗?如果有任何我错过指出的细节,请随时询问。

标签: androidkotlin

解决方案


我只是自己想办法。我需要做的只是将 和 的val args声明val selectedOrderId移到OnCreated().

class OrderDetailFragment : Fragment(), OrderedItemListOnItemClickListener {


    lateinit var adapter: OrderedItemListAdapter
    private lateinit var binding: FragmentOrderDetailBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val args = arguments?.let { OrderDetailFragmentArgs.fromBundle(it) }
        val selectedOrderId = args?.orderId

        ....
        ....
        ....

推荐阅读