从不同Fragment进入含RecyclerView的FragmentB时列表点击事件差异化实现
Fragment多来源跳转差异化点击逻辑实现方案
核心思路
通过Fragment官方推荐的arguments参数传递入口来源标记,在列表点击事件中根据标记分支执行不同逻辑,同时保证页面重建时参数不会丢失。
实现步骤
1. 为FragmentB定义来源标记和统一实例化入口
在FragmentB中预定义来源常量,封装实例化方法强制传入来源参数,避免漏传:
// 可放在FragmentB.kt顶层或者伴生对象中 const val SOURCE_FROM_A = 1 const val SOURCE_FROM_C = 2 private const val ARG_ENTRY_SOURCE = "entry_source" class FragmentB : Fragment() { // 存储当前页面来源 private var entrySource: Int = SOURCE_FROM_A companion object { // 统一实例化入口,所有跳转都走该方法 fun newInstance(source: Int): FragmentB { val fragment = FragmentB() fragment.arguments = Bundle().apply { putInt(ARG_ENTRY_SOURCE, source) } return fragment } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 页面初始化/重建时读取来源参数 arguments?.let { entrySource = it.getInt(ARG_ENTRY_SOURCE, SOURCE_FROM_A) } } }
2. 跳转时传入对应来源参数
从FragmentA跳转时传入A的来源标记:
// FragmentA中跳转逻辑示例,用Navigation或者原生Fragment事务都可以 // 方式1:用原生事务 parentFragmentManager.beginTransaction() .replace(R.id.container, FragmentB.newInstance(SOURCE_FROM_A)) .addToBackStack(null) .commit() // 方式2:用Navigation组件 findNavController().navigate( R.id.action_to_fragmentB, bundleOf(ARG_ENTRY_SOURCE to SOURCE_FROM_A) )
从FragmentC跳转时同理,传入SOURCE_FROM_C即可。
3. 列表点击事件中按来源执行不同逻辑
在RecyclerView的Item点击回调里判断来源,分支处理:
// FragmentB中给RecyclerView Adapter设置点击事件 adapter.setOnItemClickListener { itemData, position -> when (entrySource) { SOURCE_FROM_A -> { // 从A进入的点击逻辑,比如跳转详情页 val intent = Intent(requireContext(), ItemDetailActivity::class.java) intent.putExtra("item", itemData) startActivity(intent) } SOURCE_FROM_C -> { // 从C进入的点击逻辑,比如选中后返回数据给C findNavController().previousBackStackEntry ?.savedStateHandle ?.set("selected_item", itemData) findNavController().popBackStack() } } }
注意事项
- 所有跳转FragmentB的入口必须传入来源参数,不要用全局变量存储来源,避免Fragment被系统回收重建后参数丢失
- 后续新增入口来源时,只需新增常量和when分支即可,扩展成本低
- Java项目逻辑完全一致,只需替换为对应Java语法即可
内容的提问来源于stack exchange,提问作者labed AbdelJalil
相关产品推荐
相关产品推荐

