如何从RecyclerView点击监听器向另一个Fragment传递数据?
RecyclerView点击传递数据到DetailsFragment的实现方案
方案一:使用Jetpack Navigation Safe Args(推荐)
Safe Args是Jetpack Navigation官方提供的类型安全参数传递方案,能避免手动处理Bundle时的类型错误问题。
1. 配置Safe Args依赖
- 在项目根目录的
build.gradle(或build.gradle.kts)中添加插件依赖:
buildscript { dependencies { classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.7.7" } }
- 在模块的
build.gradle(或build.gradle.kts)中应用插件:
plugins { id 'androidx.navigation.safeargs.kotlin' }
2. 在导航图中定义参数
打开你的nav_graph.xml,找到action_breakfastFragment_to_DetailsFragment节点,添加需要传递的参数:
<action android:id="@+id/action_breakfastFragment_to_DetailsFragment" app:destination="@id/DetailsFragment"> <argument android:name="imageResourceId" app:argType="integer"/> <argument android:name="stringResourceId" app:argType="integer"/> <argument android:name="breakfastName" app:argType="string"/> </action>
3. 在适配器中传递参数
修改onBindViewHolder中的点击事件逻辑,用Safe Args生成的Action类封装数据:
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 { // 用Safe Args生成的Action传递参数 val action = BreakfastFragmentDirections.actionBreakfastFragmentToDetailsFragment( imageResourceId = currentBreakfast.breakfastImageResourceId, stringResourceId = currentBreakfast.breakfastStringResourceId, breakfastName = currentBreakfast.name // 假设你的Breakfast类包含name字段 ) holder.itemView.findNavController().navigate(action) showDetails(currentBreakfast) } }
4. 在DetailsFragment中接收参数
通过Safe Args生成的Args类获取传递的参数:
class DetailsFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // 解析Safe Args参数 val args = DetailsFragmentArgs.fromBundle(requireArguments()) val imageId = args.imageResourceId val stringId = args.stringResourceId val breakfastName = args.breakfastName // 用参数更新UI binding.ivDetail.setImageResource(imageId) binding.tvDetailTitle.text = getText(stringId) binding.tvDetailName.text = breakfastName return binding.root } }
方案二:使用Bundle手动传递参数
如果暂时不想接入Safe Args,可以直接通过Bundle传递数据:
1. 在适配器中传递Bundle
holder.breakfastImage.setOnClickListener { val bundle = Bundle().apply { putInt("imageResourceId", currentBreakfast.breakfastImageResourceId) putInt("stringResourceId", currentBreakfast.breakfastStringResourceId) putString("breakfastName", currentBreakfast.name) } holder.itemView.findNavController().navigate( R.id.action_breakfastFragment_to_DetailsFragment, bundle ) showDetails(currentBreakfast) }
2. 在DetailsFragment中接收参数
class DetailsFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // 从Bundle中取出参数 val imageId = arguments?.getInt("imageResourceId") ?: 0 val stringId = arguments?.getInt("stringResourceId") ?: 0 val breakfastName = arguments?.getString("breakfastName") ?: "" // 更新UI逻辑 binding.ivDetail.setImageResource(imageId) binding.tvDetailTitle.text = getText(stringId) binding.tvDetailName.text = breakfastName return binding.root } }
注意事项
- 确保你的
Breakfast数据类包含所有需要传递的字段(如name、breakfastImageResourceId等)。 - 使用Safe Args时,修改导航图后需要同步编译项目,让插件自动生成对应的Direction和Args类。
内容的提问来源于stack exchange,提问作者deja
相关产品推荐
相关产品推荐

