Android Fragments AndroidKotlin从Clerview中的点击项获取数据并在片段之间传递

8tntrjer  于 9个月前  发布在  Android
关注(0)|答案(1)|浏览(107)

所以我有两个数据类(OutletListDataClassProductListDataClass),它们目前被两个不同的片段(OutletListFragment.ktProductListFragment.kt,在导航图中直接连接)使用。
这两个片段都是OutletListFragment.kt中的clicked item,我想从OutletListFragment.kt中提取信息(包含在两个数据类中),并将其传递给ProductListFragment.kt
以下是我在两个片段中使用的数据类:

OutletListDataClass

data class OutletListPOJODataClasses(

    @SerializedName("data")
    @Expose
    var data: List<OutletListPOJODataClassesDataItem>? = null,

    @SerializedName("error")
    val error: OutletListDataClassError? = null
)


data class OutletListPOJODataClassesDataItem(
    @SerializedName("stk_prodcode")//Both data classes have this variable
    @Expose
    val stkProdcode: String? = null,

    @SerializedName("stk_allqty")
    @Expose
    val stkAllqty: Int? = null,

    @SerializedName("skt_lastupdate")
    @Expose
    val sktLastupdate: String? = null,

    @SerializedName("outlet_address")
    @Expose
    val outletAddress: String? = null,

    @SerializedName("outlet_name")
    @Expose
    val outletName: String? = null,

    @SerializedName("stk_outcode")
    @Expose
    val stkOutcode: String? = null
)

字符串

ProductListDataClass

data class ProductListPOJODataClasses(

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

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

data class ProductListDataClassError(

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

    @field:SerializedName("code")
    val code: Int? = null,

    @field:SerializedName("status")
    val status: Boolean? = null
)

data class ProductListPOJODataClassesDataItem(
    @field:SerializedName("stk_prodcode")  //Both data classes have this variable
    val stkProdcode: String? = null,

    @field:SerializedName("stk_allqty")
    val stkAllqty: Int? = null,

    @field:SerializedName("pro_saleprice")
    val proSaleprice: Int? = null,

    @field:SerializedName("skt_lastupdate")
    val sktLastupdate: String? = null,

    @field:SerializedName("stk_outcode")
    val stkOutcode: String? = null,

    @field:SerializedName("pro_name")
    val proName: String? = null
)


正如你所看到的,这两个数据类包含sa.me变量(StkOutcode)。这就是我想要提取的(从OutletListDataItem
下面是当前OutletListFragment.kt的代码片段:

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

    (activity as AppCompatActivity).supportActionBar?.title = "Product List"

    binding = DataBindingUtil.inflate(
        inflater,
        R.layout.fragment_product_stock_outlet_list,
        container,
        false
    )

    //Show Progressbar While loading data
    showProgressBar()

    //Apply layout manager
    binding.rvOutletList.layoutManager = LinearLayoutManager((activity as AppCompatActivity))

    //Fetch Outlet List Data
    fetchOutletListData()

    // Declare that this fragment has menu
    setHasOptionsMenu(true)

    // Set action bar title to "Outlet List"
    (activity as AppCompatActivity).supportActionBar?.title = "Outlet List"

    return binding.root
}


这是我为OutletListFragment创建的Clerclerview适配器。OutletListAdapter

class OutletListItemHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    fun bind(
        outlet: OutletListPOJODataClassesDataItem,
        clickListener: OutletListOnItemClickListener?
    ) {
        itemView.outletName.text = outlet.outletName

        itemView.setOnClickListener {
            clickListener?.onItemClicked(outlet)
        }
    }
}

class OutletListAdapter(private var outletList: OutletListPOJODataClasses, private val itemClickListener: OutletListOnItemClickListener)
: RecyclerView.Adapter<OutletListItemHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OutletListItemHolder {
        val v = LayoutInflater.from(parent.context).inflate(R.layout.outlet_list_item_layout, parent, false)
        return OutletListItemHolder(v)
    }

    override fun getItemCount(): Int = outletList.data!!.size

    override fun onBindViewHolder(holder: OutletListItemHolder, position: Int) {
        val outlet = outletList.data?.get(position)
        if (outlet != null) {
            holder.bind(outlet, itemClickListener)
        }
    }
}

interface OutletListOnItemClickListener{
    fun onItemClicked(outlet: OutletListPOJODataClassesDataItem)
}


如何从OutletListFragment.kt中的Data类获取想要的变量并将其传递给ProductListFragment.kt?如果有任何不清楚的地方,请告诉我。

编辑:

以下是navigation.xml的代码片段:

<fragment
    android:id="@+id/productStockOutletList"
    android:name="something.mainFragments.ProductStockOutletListFragment"
    android:label="ProductStockOutletList" >
    <action
        android:id="@+id/action_productStockOutletList_to_productListFragment"
        app:destination="@id/productListFragment"
        app:enterAnim="@android:anim/slide_in_left"
        app:exitAnim="@android:anim/slide_out_right"
        app:popEnterAnim="@android:anim/slide_in_left"
        app:popExitAnim="@anim/slide_out_left" />
</fragment>

<fragment
    android:id="@+id/productListFragment"
    android:name="something.mainFragments.ProductListFragment"
    android:label="ProductListFragment" />

p4tfgftt

p4tfgftt1#

如果您使用的是Jetpack Navigation(因为您指的是“导航图”之类的东西,所以很明显您使用的是Jetpack Navigation),那么要在导航目标之间传递参数,您必须定义一个<action,其中包含正确的arguments,然后将其作为可打包数据的某种变体传递给其他片段。
这是文件中的示例:

<action android:id="@+id/startMyFragment"
    app:destination="@+id/myFragment">
    <argument
        android:name="myArg"
        app:argType="integer"
        android:defaultValue="1" />
</action>

字符串
所以在你的情况下,你应该需要这样的东西

<navigation ...>
    <action android:id="@+id/toProductListFragment"
        app:destination="@+id/productListFragment">
        <argument
            android:name="stkProdcode"
            app:argType="string" />
    </action>


显然,只有在您启用safeargs插件的情况下,这些东西才有效(否则您必须自己“记住”这个键,或者手动编写NavDirections类,或者自己组装Bundle--无论哪种方式,Jetpack Navigation都希望您使用Safeargs来传递参数):

buildscript {
    dependencies {
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.2.2"


apply plugin: "androidx.navigation.safeargs.kotlin"


然后你就可以

class OutletListFragment: Fragment(), OutletListOnItemClickListener {
    ....

    override fun onItemClicked(outlet: OutletListPOJODataClassesDataItem) {
        Navigation.findNavController(view).navigate(NavigationDirections.toProductListFragment(outlet.stkProdcode))
    }
}


由于Jetpack Navigation的限制,您还必须将参数定义复制到<fragment标记中:

<fragment
    android:id="@+id/productListFragment"
    android:name="com.example.switchingandroidappproject.mainFragments.ProductListFragment"
    android:label="ProductListFragment" >
    <argument
        android:name="stkProdcode"
        app:argType="string" />
</fragment>


请确保不要输入错误(android:name不匹配),因为这样会遇到意外故障)。
现在你可以得到你的论点在另一边为

val args = ProductListFragmentArgs.fromBundle(getArguments())
val code = args.stkProdcode


我并不真正使用Jetpack Navigation,所以我很惊讶地发现,您必须将片段参数复制到操作参数,但您已经完成了。
......我想用什么来代替Jetpack Navigation,这就像

// send
backstack.goTo(ProductListScreen(stkProdCode))
// receive
val prodCode = getKey<ProductListScreen>().stkProdCode


而且就像(如果不是更多的话)类型安全。🙄

相关问题