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

Cupertino日期选择器长滑年份轮越界抛出_AssertionError异常解决咨询

问题

在Android应用中,操作Cupertino日期选择器的年份轮进行“长滑”,使其越过设置的最小或最大年份时,会抛出如下断言异常:

Exception has occurred.
_AssertionError ('package:flutter/src/cupertino/date_picker.dart': Failed assertion: line 327 pos 10: '(mode != CupertinoDatePickerMode.date && mode != CupertinoDatePickerMode.monthYear) ||
             (minimumYear >= 1 && (initialDateTime ?? DateTime.now()).year >= minimumYear)': initial year is not greater than minimum year, or minimum year is not positive)

已正确设置initialDateTime为DateTime.now()、minimumYear=2000、maximumYear=2050,但异常仍会触发。

完整代码如下:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: const MyHomePage());
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  DateTime _dateTime = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).primaryColor,
        title: const Text("Inbuild Cupertino Date Picker Example"),
      ),
      body: Column(
        children: [
          Flexible(
            child: CupertinoDatePicker(
              initialDateTime: _dateTime,
              dateOrder: DatePickerDateOrder.ymd,
              mode: CupertinoDatePickerMode.date,
              minimumYear: 2000,
              maximumYear: 2050,
              onDateTimeChanged: (newDateTime) {
                print("############## DateTime: ${newDateTime}");
                setState(() {
                  _dateTime = newDateTime;
                });
              },
            ),
          ),
        ],
      ),
      bottomNavigationBar: Container(
        padding: EdgeInsets.all(15.0),
        height: 60.0,
        width: double.infinity,
        decoration: BoxDecoration(color: Colors.amberAccent),
        child: const Text("Bottom Navigation Bar"),
      ),
    );
  }
}

解决方法

问题根源是长滑操作时,Cupertino日期选择器会临时生成超出minimumYear/maximumYear范围的日期实例,触发内部的断言检查。解决思路是在更新状态前,先对新日期做范围校验,确保年份始终在设定的区间内:

  1. 在onDateTimeChanged回调中,先判断新日期的年份是否超出范围
  2. 若超出,则修正为对应边界年份的有效日期(保持原月日,若原月日在边界年份无效则自动调整为当月最后一天)
  3. 再将修正后的日期更新到状态中

修改后的onDateTimeChanged代码如下:

onDateTimeChanged: (newDateTime) {
  print("############## DateTime: ${newDateTime}");
  DateTime adjustedDateTime = newDateTime;
  // 校验并修正年份范围
  if (adjustedDateTime.year < 2000) {
    adjustedDateTime = DateTime(2000, adjustedDateTime.month, adjustedDateTime.day);
  } else if (adjustedDateTime.year > 2050) {
    adjustedDateTime = DateTime(2050, adjustedDateTime.month, adjustedDateTime.day);
  }
  setState(() {
    _dateTime = adjustedDateTime;
  });
},

也可以封装成通用方法,方便复用:

DateTime _adjustDateTimeToRange(DateTime date, int minYear, int maxYear) {
  if (date.year < minYear) {
    return DateTime(minYear, date.month, date.day);
  } else if (date.year > maxYear) {
    return DateTime(maxYear, date.month, date.day);
  }
  return date;
}

// 在回调中使用
onDateTimeChanged: (newDateTime) {
  print("############## DateTime: ${newDateTime}");
  setState(() {
    _dateTime = _adjustDateTimeToRange(newDateTime, 2000, 2050);
  });
},

这样处理后,长滑操作时生成的超出范围的日期会被提前修正,不会触发断言异常,同时保证用户选择的日期始终在设定的年份区间内。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 09:10:09