《Android 編程權威指南》學習筆記 : 第13章 對話框

第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() {
  
        ...
        // 日期按鈕
        dataButton.setOnClickListener {
            DatePickerFragment.newInstance(crime.date).apply {
                // setTargetFragment(this@CrimeFragment, REQUEST_DATE)  // setTargetFragment() 已被棄用
                show([email protected], 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章