第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
本書使用的以下兩個方法已經棄用:
- setTargetFragment(...)
- getTargetFragment()
故,這裏將使用以下兩個方法:
- 父fragment設置監聽: parentFragmentManager.setFragmentResultListener(...)
- 在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