DialogFragment中targetFragment已弃用,Kotlin代码如何替换实现回调
Android Kotlin DialogFragment targetFragment弃用替代方案
官方自AndroidX Fragment 1.3.0起正式弃用targetFragment相关API,推荐使用Fragment Result API替代实现Fragment间的回调通信,以下是可直接复用的修改方案:
方案1:使用官方推荐的Fragment Result API(首选,自动适配配置变更)
第一步:修改SortDialogFragment代码
class SortDialogFragment: DialogFragment() { // 定义Result相关常量,避免硬编码 companion object { const val SORT_RESULT_KEY = "sort_dialog_result" const val SORT_DESC_KEY = "sort_desc" } private lateinit var radioGroup: RadioGroup override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(requireContext()) val inflater = requireActivity().layoutInflater val view: View = inflater.inflate(R.layout.fragment_dialog_sort, null) radioGroup = view.findViewById(R.id.sort_RG) builder.setView(view) .setPositiveButton("OK") { _, _ -> val sortDesc = when(radioGroup.checkedRadioButtonId){ R.id.sort_desc_RB -> true R.id.sort_asc_RB -> false else -> true // 可根据需求调整默认值 } // 发送结果给父Fragment parentFragmentManager.setFragmentResult( SORT_RESULT_KEY, bundleOf(SORT_DESC_KEY to sortDesc) ) dismiss() } .setNegativeButton("Cancel") { _, _ -> dismiss() } // 注意:原代码返回super.onCreateDialog会导致自定义布局不生效,需返回builder创建的实例 return builder.create() } // 可删除原有的OnItemClickDialogListener接口、listener变量、onAttach内的targetFragment相关逻辑 }
第二步:在发起弹窗的父Fragment中注册结果监听
在父Fragment的onViewCreated方法中添加监听逻辑:
// 注册排序弹窗结果监听 childFragmentManager.setFragmentResultListener( SortDialogFragment.SORT_RESULT_KEY, viewLifecycleOwner ) { _, bundle -> val sortDesc = bundle.getBoolean(SortDialogFragment.SORT_DESC_KEY) // 在这里处理排序逻辑,替代原来的onItemClickDialog回调 doSort(sortDesc) }
发起弹窗的代码保持正常调用即可:
// 打开排序弹窗 SortDialogFragment().show(childFragmentManager, "sort_dialog")
方案2:直接传入回调Lambda(适合简单场景)
如果不想用Result API,也可以通过回调参数的方式实现,代码更直观:
修改后的SortDialogFragment代码
class SortDialogFragment: DialogFragment() { var onSortSelected: ((sortDesc: Boolean) -> Unit)? = null private lateinit var radioGroup: RadioGroup override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val builder = AlertDialog.Builder(requireContext()) val inflater = requireActivity().layoutInflater val view: View = inflater.inflate(R.layout.fragment_dialog_sort, null) radioGroup = view.findViewById(R.id.sort_RG) builder.setView(view) .setPositiveButton("OK") { _, _ -> val sortDesc = when(radioGroup.checkedRadioButtonId){ R.id.sort_desc_RB -> true R.id.sort_asc_RB -> false else -> true } onSortSelected?.invoke(sortDesc) dismiss() } .setNegativeButton("Cancel") { _, _ -> dismiss() } return builder.create() } }
父Fragment调用代码
SortDialogFragment().apply { onSortSelected = { sortDesc -> // 处理排序逻辑 doSort(sortDesc) } }.show(childFragmentManager, "sort_dialog")
注意:如果页面发生配置变更(如横竖屏旋转)导致弹窗重建,回调会丢失,需要在父Fragment重建时重新给弹窗实例赋值回调,因此复杂场景优先选择方案1。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

