android-fragments 如何将数据从RecyclerView的click侦听器传递到另一个片段?

ozxc1zmp  于 2022-11-13  发布在  Android
关注(0)|答案(2)|浏览(175)

在我的程序中,我有一个带有适配器的RecyclerView,我在其中检查单击了RecyclerView的哪个元素。

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val currentBreakfast = breakfastList[position]
    holder.breakfastTitle.text = context.getText(currentBreakfast.breakfastStringResourceId)
    holder.breakfastImage.setImageResource(currentBreakfast.breakfastImageResourceId)

    holder.breakfastImage.setOnClickListener {
        holder.itemView.findNavController().navigate(R.id.action_breakfastFragment_to_DetailsFragment)
        showDetails(currentBreakfast)
    }
}

我想将有关特定单击元素的数据(如imageIdstringIdName等)传递给另一个片段DetailsFragment,我想在其中显示更多数据
我该怎么做呢?

ff29svar

ff29svar1#

你需要把你的片段发送到你调用的适配器,我猜它是breakfastFragment,只要把this加到它上面:

BreakfastAdapter(
                requireActivity(),
                breakfastList,
                this
            )

您的适配器将获得fragment

open class BreakfastAdapter(
    private val context: Context,
    private var breakfastList: ArrayList<Breakfast>,
    private val fragment: Fragment
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

你可以使用fragment来导航它:

holder.breakfastImage.setOnClickListener {
// create a bundle to hold data you want to send
 val bundle = bundleOf(
   "breakfastImageResourceId" to currentBreakfast.breakfastImageResourceId,
   "breakfastStringResourceId" to currentBreakfast.breakfastStringResourceId,
   "kcal" to currentBreakfast.kcal
 )
// add this bundle when you move to another fragment.              
fragment.findNavController().navigate(R.id.action_breakfastFragment_to_DetailsFragment, bundle)
}

在另一个片段中获取该值,并在日志中查看它们,如下所示:

// create below variables
private var mBreakfastImageResourceId: Int = 0
private var mBreakfastStringResourceId: Int = 0
private var mKcal: Int = 0

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Now we set above values with what we sent from adapter
        arguments?.let {
            if (it["breakfastImageResourceId"] != null) {
                mBreakfastImageResourceId = it.getInt("BreakfastImageResourceId")!!
            }
            if (it["breakfastStringResourceId"] != null) {
                mBreakfastStringResourceId = it.getInt("breakfastStringResourceId")!!
            }
            if (it["kcal"] != null) {
                mKcal = it.getInt("kcal")!!
            }
        }
        return inflater.inflate(R.layout.fragment_question_stats, container, false)
    }

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // now you can do whatever you want with mBreakfastImageResourceId, mBreakfastStringResourceId and mKcal.

}

我只是编造了一些变量名和类名,因为你没有分享它们,只是用你正确的名字来改变它。

wsewodh2

wsewodh22#

有几种方法。
我建议你看一下这个答案(公认答案):How to pass data from adapter to fragment?
然后转到名为“更多的Kotlin方法是忽略接口,只传递一个函数”的部分。
这是我自己也在使用的方法。
下面是如何定义RecyclerView的适配器的示例:

class ReportAdapter(var reports: List<Report>,val clickFunc : (Report) -> (Unit)) :  RecyclerView.Adapter<ReportAdapter.ViewHolder>() {...}

然后,您需要将回调函数附加到Viewholder中的click侦听器-在我的示例中,它看起来像这样(列表中的每个项目都有一个cardview -在xml文件中定义):

itemView.report_cardview_item.setOnClickListener {
                clickFunc(report)
            }

然后,在传递给RecylerView Adapter的回调函数中,您可以导航到包含相关数据的details片段--我的一个回调函数(在创建时传递给Adapter)看起来如下所示(在“拥有”RecylerView的Fragment中定义):

private fun reportClicked(report:Report)
    {
        val action = ReportsFragmentDirections.actionNavReportsToReportDetailFragment(report)
        findNavController().navigate(action)
    }

(here使用我的导航图创建用于NavController的Action)
我的适配器很容易用一些数据和对回调函数的引用进行初始化:

adapter = ReportAdapter(reports,::reportClicked)

相关问题