如何在Activity中使用setFragmentResultListener接收Fragment返回数据?
解决办法
首先检查拼写错误:你的Activity中设置监听器用的是"reqeust code",而Fragment发送数据用的是"request code",拼写不一致会直接导致监听器无法匹配到结果,先修正这个拼写错误。
如果修正拼写后仍无效,核心问题出在FragmentResult的作用域:
Fragment的setFragmentResult是基于所属的FragmentManager传递数据的。当使用Navigation组件时,被导航的Fragment属于NavHostFragment的childFragmentManager,而你在Activity中通过supportFragmentManager设置的监听器,和Fragment所在的FragmentManager不属于同一层级,因此无法接收到数据。
针对这个问题,有两种可靠的解决方式:
方式一:使用Navigation组件的SavedStateHandle(推荐)
利用NavController的SavedStateHandle传递返回数据,这是Navigation组件官方推荐的跨层级数据传递方案:
- 在Fragment中,通过
previousBackStackEntry的SavedStateHandle设置返回数据:
// Fragment中返回数据 findNavController().previousBackStackEntry?.savedStateHandle?.set("request code", bundleOf())
- 在Activity中,通过当前NavController的
currentBackStackEntry获取SavedStateHandle并监听数据:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityHomeBinding.inflate(layoutInflater) setContentView(binding.root) val navController = findNavController(R.id.nav_host_fragment) // 监听返回的数据 navController.currentBackStackEntry?.savedStateHandle?.getLiveData<Bundle>("request code")?.observe(this) { resultBundle -> // 处理返回的数据 } }
方式二:使用NavHostFragment的childFragmentManager设置监听器
直接在NavHostFragment的childFragmentManager上设置监听器,因为被导航的Fragment属于这个FragmentManager的层级:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityHomeBinding.inflate(layoutInflater) setContentView(binding.root) // 获取NavHostFragment实例(替换为你布局中NavHost的实际ID) val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment // 在NavHost的子FragmentManager上设置监听器 navHostFragment.childFragmentManager.setFragmentResultListener("request code", this) { _, resultBundle -> // 处理返回的数据 } }
内容的提问来源于stack exchange,提问作者jack_the_beast
相关产品推荐
相关产品推荐

