如何将DateDialogFragment选中的日期传递至其他Fragment?
DateDialogFragment日期传递至其他Fragment的问题
我希望使用DateDialogFragment,并将从中获取的日期传递至另一个Fragment。请问在获取Calendar实例并设置日期后,该如何传递此日期?我了解到Parcelable,但不清楚如何使用它!我曾尝试用Long类型处理日期,但数据库无法进行数据比较,因此尝试使用SQLite的Parcelable。
我的代码如下:
class DateDialogFragment : DialogFragment(), DatePickerDialog.OnDateSetListener { private val calendar = Calendar.getInstance() override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val year = calendar.get(Calendar.YEAR) val month = calendar.get(Calendar.MONTH) val dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH) return DatePickerDialog(requireActivity(), this, year, month, dayOfMonth) } override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) { calendar.set(Calendar.YEAR, year) calendar.set(Calendar.MONTH, month) calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth) val selectedDate = calendar.time val selectedDateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.JAPAN).format(calendar.time) val bundle = Bundle() bundle.putString("SELECTED_DATE", selectedDateFormat) bundle.putParcelable("SELECTED_DATE_PARCELABLE", selectedDate) setFragmentResult("REQUEST_KEY", bundle) } }
问题修正与解决方案
1. 你当前代码的错误点
Date类本身实现的是Serializable接口,而非Parcelable,所以你用bundle.putParcelable("SELECTED_DATE_PARCELABLE", selectedDate)是无效的,应该替换为:
bundle.putSerializable("SELECTED_DATE_SERIALIZABLE", selectedDate)
接收方Fragment获取时:
val selectedDate = bundle.getSerializable("SELECTED_DATE_SERIALIZABLE") as? Date
2. 日期传递的三种可行方案
方案一:传递格式化字符串(最适合数据库操作)
你代码里的selectedDateFormat(yyyy-MM-dd格式)完全可以满足需求:
- 传递时直接用
bundle.putString("SELECTED_DATE", selectedDateFormat) - 接收方直接
getString获取,既可以用于显示,也能直接存入SQLite。SQLite支持对yyyy-MM-dd格式的字符串进行日期比较,比如:
也可以用SQLite的SELECT * FROM your_table WHERE date_column >= '2024-05-01'DATE()函数做更复杂的日期运算:SELECT * FROM your_table WHERE DATE(date_column) >= DATE('now', '-7 days')
方案二:传递时间戳(Long类型)
你之前说数据库无法比较时间戳,大概率是操作方式有误。时间戳是Long类型的数值,SQLite支持直接数值比较:
- 传递时:
bundle.putLong("SELECTED_TIMESTAMP", selectedDate.time) - 接收方:
val timestamp = bundle.getLong("SELECTED_TIMESTAMP") - 数据库查询示例:
SELECT * FROM your_table WHERE timestamp_column >= 1714521600000 -- 对应2024-05-01的时间戳
方案三:使用Parcelable封装日期对象
如果需要传递强类型的日期对象(比如LocalDate),可以用Kotlin的@Parcelize注解快速实现Parcelable:
- 首先在app模块的
build.gradle中启用插件:plugins { id 'kotlin-parcelize' } - 创建Parcelable包装类:
@Parcelize data class DateWrapper(val localDate: LocalDate) : Parcelable - 在
DateDialogFragment的onDateSet中转换并传递:// Calendar的month从0开始,LocalDate的month从1开始,注意+1 val selectedLocalDate = LocalDate.of(year, month + 1, dayOfMonth) val bundle = Bundle() bundle.putParcelable("SELECTED_LOCAL_DATE", DateWrapper(selectedLocalDate)) setFragmentResult("REQUEST_KEY", bundle) - 接收方Fragment获取:
setFragmentResultListener("REQUEST_KEY") { _, bundle -> val dateWrapper = bundle.getParcelable<DateWrapper>("SELECTED_LOCAL_DATE") val selectedLocalDate = dateWrapper?.localDate // 处理日期逻辑 }
内容的提问来源于stack exchange,提问作者wish
相关产品推荐
相关产品推荐

