如何将BottomSheetFragment的数据传递给同Activity下的Fragment
问题根因
你的代码存在两处核心问题:
- 语法错误:你为
HomeFragment实例myFragment设置了携带数据的arguments,但执行replace事务时传入的是新创建的无参HomeFragment实例,导致你设置的参数完全没有被传递到展示的Fragment中。 - 设计问题:如果你的
HomeFragment已经是HomeActivity底部导航对应存在的实例,不需要重复创建替换,使用官方推荐的Fragment数据传递方案更合理,避免原有状态丢失。
修正方案
推荐优先使用官方原生的Fragment Result API实现,无需修改宿主Activity、无需操作Fragment事务,适配性最高。
方案1:使用Fragment Result API传递数据
步骤1:在接收数据的HomeFragment中注册结果监听
class HomeFragment : BaseFragment() { private var filterCategory: String?= null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 注册结果监听,requestKey要和发送方保持一致 setFragmentResultListener("category_request_key") { _, bundle -> filterCategory = bundle.getString("category") // 拿到数据后可在此处执行后续逻辑,比如刷新列表 } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentHomeBinding.inflate(inflater, container, false) return binding.root } }
步骤2:修改HomeBottomSheetFragment的点击事件发送数据
categoryAdapter.setOnClickListener(object :CategoryListAdapter.OnClickListener{ override fun onClick(position: Int, category: ProdCategories) { // 构造结果Bundle val resultBundle = Bundle() resultBundle.putString("category", category.category_name) // 发送结果,requestKey和接收方注册的key一致 setFragmentResult("category_request_key", resultBundle) // 发送完成后关闭底部弹窗 dismiss() } })
方案2:通过宿主Activity接口回调(适合需要Activity做中间处理的场景)
步骤1:定义回调接口
interface OnCategorySelectListener { fun onCategorySelected(categoryName: String) }
步骤2:让HomeActivity实现这个接口
class HomeActivity : AppCompatActivity(), OnCategorySelectListener { override fun onCategorySelected(categoryName: String) { // 获取当前已经存在的HomeFragment实例 val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val homeFragment = navHostFragment.childFragmentManager.fragments.firstOrNull { it is HomeFragment } as? HomeFragment // 赋值/调用HomeFragment的方法执行逻辑 homeFragment?.filterCategory = categoryName // 也可在此处切换底部导航到首页Tab } }
步骤3:在HomeBottomSheetFragment触发回调
categoryAdapter.setOnClickListener(object :CategoryListAdapter.OnClickListener{ override fun onClick(position: Int, category: ProdCategories) { val listener = requireActivity() as? OnCategorySelectListener listener?.onCategorySelected(category.category_name) dismiss() } })
(不推荐)修复原有事务写法的错误
如果你一定要用替换Fragment的方式实现,只需要把replace方法的第二个参数换成你已经设置了arguments的myFragment即可,但该方案会重建Fragment,导致原有状态丢失:
categoryAdapter.setOnClickListener(object :CategoryListAdapter.OnClickListener{ override fun onClick(position: Int, category: ProdCategories) { val myFragment = HomeFragment() val bundle = Bundle() bundle.putString("category", category.category_name) myFragment.arguments = bundle // 替换为已经设置了参数的myFragment,而非新创建的实例 fragmentManager?.beginTransaction()?.replace(R.id.nav_host_fragment,myFragment)?.commit() } })
内容的提问来源于stack exchange,提问作者Codist
相关产品推荐
相关产品推荐

