首页 > 技术文章 > 《Android 编程权威指南》学习笔记 : 第13章 对话框

easy5weikai 2022-05-31 23:37 原文

第13章 对话框

《Android 编程权威指南》学习笔记系列目录 :https://www.cnblogs.com/easy5weikai/p/16322845.html

本节要点

把Dialog封装到fragment中

把Dialog封装到fragment中,保证旋转后,对话框重建时能恢复

父fragment传递数据给子fragment

子fragment 定义伴生对象方法 newInstance(date: Date),父fragment在创建子fragment时就能把数据date传入。
而子fragment把数据保存在 Fragment Argument中,保证屏幕旋转后能重建后恢复。

private const val ARG_DATE = "date"

class DatePickerFragment : DialogFragment() {
  
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val date = arguments?.getSerializable(ARG_DATE) as Date //从Fragment Argument中获取数据,保证屏幕旋转后能重建后恢复
        val calendar = Calendar.getInstance()
        calendar.time = date
        ...
    }
    ...
    companion object {
        fun newInstance(date: Date): DatePickerFragment{
            val args = Bundle().apply {
                putSerializable(ARG_DATE, date)
            }

            return DatePickerFragment().apply {
                arguments = args
            }
        }
    }
}

子fragment传递数据给父父fragment

本书使用的以下两个方法已经弃用:

  1. setTargetFragment(...)
  2. getTargetFragment()

故,这里将使用以下两个方法:

  1. 父fragment设置监听: parentFragmentManager.setFragmentResultListener(...)
  2. 在fragment设置结果: parentFragmentManager?.setFragmentResult(...)

父Fragment:CrimeFragment:

const val REQUEST_KEY_DATE = "request_date" //日期请求码
class CrimeFragment : Fragment() {
    ...
    override fun onStart() {
  
        ...
        // 日期按钮
        dateButton.setOnClickListener {
            DatePickerFragment.newInstance(crime.date).apply {
                // setTargetFragment(this@CrimeFragment, REQUEST_DATE)  // setTargetFragment() 已被弃用
                show(this@CrimeFragment.parentFragmentManager, DIALOG_DATE) // 显示子fragmen
            }
        }

        // 监听日期请求码的结果
        parentFragmentManager.setFragmentResultListener(
            REQUEST_KEY_DATE,  // 日期请求码
            this@CrimeFragment // 生命周期持有者
        ) { _, bundle ->      // 执行函数
            val resultDate = bundle.getSerializable(DATE_PICKER_RESULT_DATE) as Date
            crime.date = resultDate
            updateUI()
        }
   }

子fragment: DatePickerFragment

const val DATE_PICKER_RESULT_DATE = "result_date"

class DatePickerFragment : DialogFragment() {
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    ...
    val dateListener = DatePickerDialog.OnDateSetListener { 
            _: DatePicker, year: Int, month: Int, day: Int ->

            val resultDate: Date = java.util.GregorianCalendar(year,month, day).time
             parentFragmentManager?.setFragmentResult(
                REQUEST_KEY_DATE, // 为日期请求码设置结果
                bundleOf(DATE_PICKER_RESULT_DATE to resultDate))
        }

        return DatePickerDialog(
            requireContext(),
            dateListener, //监听器
            initialYear,
            initialMonth,
            initialDay
        )
   }
}

参考资料:
https://blog.csdn.net/winskyan/article/details/118406967
https://www.bilibili.com/read/cv13770982

推荐阅读