Flutter 时间日期选择器 DatePicker 使用笔记

项目中使用到时间日期选择器 Flutter DatePicker ,将碰到的一些问题整理成笔记分享在这,希望能帮到有需要的人。

DatePicker显示中文

Flutter 内嵌 DatePickerDialog ,我们直接showDatePicker就能构造使用。但这里有个问题,控件显示出来的语言是英语。

    showDatePicker(
        context: context,
        initialDate: _showDate,
        firstDate: DateTime(2020),
        lastDate: DateTime(2024));

现在对这个语言做处理,因为这个控件是 Flutter 提供的,要添加对其他语言的国际化适配,也只要使用 Flutter 提供的依赖就行

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: any

Flutter 提供很多控件,比如 Android Material、iPhone Components,现在我们都将它添加到国际化适配工厂。以后如果有用到这些控件,也可以将语言处理成本地语言。

  localizationsDelegates: [
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],

再添加要兼容支持的语言,比如我这添加中文和英文。

    supportedLocales: [
        Locale('en'),
        Locale('zh'),
      ],

上面的意思,当我们手机系统语言是中文时,Flutter 提供的控件文本会显示成对应中文。那如果你想添加其他国家支持,这是其他国家语言代码,仅供参考,有些国家可能 Flutter 本身也没做翻译兼容。

英语:Locale('en')
简体中文:Locale('zh')
繁体中文:Locale('zh', 'TW')
日语:Locale('ja')
韩语:Locale('ko')
法语:Locale('fr')
西班牙语:Locale('es')
德语:Locale('de')
意大利语:Locale('it')
葡萄牙语:Locale('pt')
俄语:Locale('ru')
土耳其语:Locale('tr')
阿拉伯语:Locale('ar')
希腊语:Locale('el')
印地语:Locale('hi')
印度尼西亚语:Locale('id')
马来语:Locale('ms')
越南语:Locale('vi')
泰语:Locale('th')
乌克兰语:Locale('uk')

这是全部代码,你们按照自己需求修改

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        Locale('en'),
        Locale('zh'),
      ],
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home:  DatePickerPage(),
    );
  }
}

选择时间

现在我界面上有两个控件,一个文本,一个按钮,点击按钮弹出日期选择器。

class _DatePickerPageState extends State<DatePickerPage> {
  DateTime _showDate = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("DatePicker")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text(_showDate.toString()),
            TextButton(onPressed: _clickDatePicker, child: Text("选择日期"))
          ],
        ),
      ),
    );
  }

  void _clickDatePicker() {
    showDatePicker(
        context: context,
        initialDate: _showDate,
        firstDate: DateTime.parse("2020-12-12 12:12:00"),
        lastDate: DateTime(2024));
  }
}

showDatePicker 三个必选参数很容易理解

  • initialDate,打开 DatePickerDialog 显示的时间
  • firstDate、lastDate 都是同理,填入一个 DateTime,分别代表能选择的最小值和最大值。比如我上面填入的时间 2020-12-12(也可以 2020),这个时间之前的都是灰色,无法点击。

一般来说,点击确定后,我们需要在界面上获取选择的值。

 void _clickDatePicker() async {
    var value = await showDatePicker(
        context: context,
        initialDate: _showDate,
        firstDate: DateTime.parse("2020-12-12 12:12:00"),
        lastDate: DateTime(2024));

    setState(() {
      this._showDate = value!;
    });
  }

格式化时间

默认显示的 DateTime 字符串是 2023-03-08 00:00:00.000 ,有可能不符合我们的界面展示需求,比如要这样显示 2023/03/08 这个时间。建议用 date_format 处理。

dependencies:
  date_format: ^2.0.7

官方提供了很多使用案例,我贴在这,应该很容易理解。

print(formatDate(DateTime(1989, 02, 21), [yyyy, '-', mm, '-', dd])); // 1989-02-21

print(formatDate(DateTime(1989, 2, 21), [yy, '-', M, '-', d])); // 89-feb-21

那我们这就可以如此写

print(formatDate(_showDate,[yyyy, '/', mm, '/', dd]));  // 2023/03/09

过去一周

这种需求还挺常见的,比如获取上一周的数据,过去三天,一个月等等,Flutter 并没提供这样的 API,只能手动算。

过去三天

Text("当前时间:${formatDate(_showDate,[yyyy, '/', mm, '/', dd])}"),
Text("过去三天:${formatDate(_showDate.subtract(Duration(days: 3)),[yyyy, '/', mm, '/', dd])}"),

只要你的天数是对的,DateTime.subtract(Duration(days: )) 可以计算出过去时间,并且还会换算每个月的最大天数。所以过去三天,过去一周都能这样计算,但过去一个月就不行,因为每个月的最大天数不固定。

过去一个月,我目前是这样计算的

Text("上个月:${formatDate(DateTime(_showDate.year,_showDate.month-1,_showDate.day),[yyyy, '/', mm, '/', dd])}"),

还有一种需求,获取当月最后一天,比如 2 月就是 28, 3 月最后一天是 31。

Text("当月最后一天:${DateTime(_showDate.year,_showDate.month+1,0).day}"),

将选择的月份加 1,然后将日设置成 0,再获取 DateTime.day 就能获取选择月份的最后一天。

本文由老郭种树原创,转载请注明:https://guozh.net/flutter-datepicker/

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注