You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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格式的字符串进行日期比较,比如:
    SELECT * FROM your_table WHERE date_column >= '2024-05-01'
    
    也可以用SQLite的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:

  1. 首先在app模块的build.gradle中启用插件:
    plugins {
        id 'kotlin-parcelize'
    }
    
  2. 创建Parcelable包装类:
    @Parcelize
    data class DateWrapper(val localDate: LocalDate) : Parcelable
    
  3. 在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)
    
  4. 接收方Fragment获取:
    setFragmentResultListener("REQUEST_KEY") { _, bundle ->
        val dateWrapper = bundle.getParcelable<DateWrapper>("SELECTED_LOCAL_DATE")
        val selectedLocalDate = dateWrapper?.localDate
        // 处理日期逻辑
    }
    

内容的提问来源于stack exchange,提问作者wish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 09:10:35