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

Flutter中如何通过Widget传递showDatePicker数据至更新页面

Flutter日期传递与初始化问题

我是Flutter新手,尝试将showDatePicker选择的_selectedDate传递到更新页面,并希望在更新页面把该日期设为默认值。目前通过Navigator.of(context).push(MaterialPageRoute())传递日期,但更新页面始终显示当前日期,直接设置_selectedDate = widget.date还会报错。

首页跳转代码

Navigator.of(context).push(
  MaterialPageRoute(
    builder: (context) => UpdatingTaskPage(
      id: _task.id!,
      title: _task.title!,
      note: _task.note!,
      isCompleted: false,
      date: _task.date!,
      startTime: _task.startTime!,
      endTime: _task.endTime!,
      color: _task.color!,
      remind: _task.remind!,
      repeat: _task.repeat!,
    ),                                   
  ),
); 

更新页面代码

class UpdatingTaskPage extends StatefulWidget {
  final String date;

  const UpdatingTaskPage(
      {super.key,
      required this.date,
});

  @override
  State<UpdatingTaskPage> createState() => _UpdatingTaskPageState();
}

class _UpdatingTaskPageState extends State<UpdatingTaskPage> {
  static TaskController controller = Get.put(TaskController());
  final task = controller.tasks.length;

  late DateTime _selectedDate = DateTime.now();

// 设置初始状态为已有值
  @override
  void initState() {
    _startTime = widget.startTime;
    _endTime = widget.endTime;
    _selectedRemind = widget.remind;
    _selectedRepeat = widget.repeat;
    _selectedColor = widget.color;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    titleController.text = widget.title;
    noteController.text = widget.note;
    return Scaffold(
      appBar: AppBar(
        title: const Text("Update task!"),
        centerTitle: true,
        actions: [
          IconButton(
              onPressed: () {
                // 退出登录按钮
                AuthController.instance.logout();
              },
              icon: const Icon(Icons.logout_rounded))
        ],
      ),
      body:
          Container(
        padding: const EdgeInsets.symmetric(horizontal: 20.0),
        child: SingleChildScrollView(
          child: Column(
            children: [         
              // 日期输入项
              InputField(
                title: 'Date',
                hint: DateFormat.yMd().format(_selectedDate),
                child: IconButton(
                  onPressed: () => _getDateFromUser(),
                  icon: const Icon(
                    Icons.calendar_today_outlined,
                    color: Colors.grey,
                  ),
                ),
              ),         
      );
  }

  _getDateFromUser() async {
    DateTime? _pickedDate = await showDatePicker(
      context: context,
      initialDate: _selectedDate,
      firstDate: DateTime(2020),
      lastDate: DateTime(2030),
    );
    if (_pickedDate != null) {
      setState(() {
        _selectedDate = _pickedDate;
      });
    } else {
      print('未选择日期!');
    }
  }
}

问题现象

  • 更新页面日期始终显示当前日期,而非传递过来的选中日期
  • 直接设置_selectedDate = widget.date时出现类型不匹配错误

修复方案

1. 解决类型不匹配问题

widget.date是String类型,_selectedDate是DateTime类型,直接赋值会触发类型错误。需要把字符串日期解析成DateTime对象。

2. 修正初始化逻辑

当前_selectedDate默认值是DateTime.now(),且initState里未更新它,导致始终显示当前日期。需在initState中解析传递的日期字符串并赋值。

修改后的代码:

class _UpdatingTaskPageState extends State<UpdatingTaskPage> {
  // ... 其他代码
  
  // 移除默认值,等待initState初始化
  late DateTime _selectedDate;

  @override
  void initState() {
    _startTime = widget.startTime;
    _endTime = widget.endTime;
    _selectedRemind = widget.remind;
    _selectedRepeat = widget.repeat;
    _selectedColor = widget.color;
    
    // 解析传递的字符串日期,和首页格式化格式保持一致
    try {
      _selectedDate = DateFormat.yMd().parse(widget.date);
    } catch (e) {
      // 解析失败时 fallback 到当前日期
      _selectedDate = DateTime.now();
      print('日期解析失败: $e');
    }
    
    super.initState();
  }

  // ... 其他代码
}

3. 确保依赖正确

如果还没导入intl包,需要在pubspec.yaml中添加:

dependencies:
  intl: ^0.18.1

内容的提问来源于stack exchange,提问作者I Can Done

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 14:36:05