你真的會用Flutter日期類元件嗎
阿新 • • 發佈:2020-05-09
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073650029-64800718.png)
> Flutter系統提供了一些日期選擇類元件,比如DayPicker、MonthPicker、YearPicker、showDatePicker、CupertinoDatePicker等,其中前4個為Material風格元件,最後一個為iOS風格元件。本文介紹了控制元件的基本用法及如何實現國際化,如果系統提供的國際化不滿足你的需要,最後也介紹瞭如何實現自定義國際化。
## DayPicker
顯示給定月份的日期,並允許選擇一天。這些天以矩形網格排列,一週的每一天都有一列。
DayPicker有幾個必填引數,分別如下:
- selectedDate:選中的日期,選中的日期有圓形背景。
- currentDate:當前日期,文字高亮。
- onChanged:使用者選擇的日期發生變化時回撥。
- firstDate:可選日期的開始值。
- lastDate:可選日期的結束值。
- displayedMonth:顯示的月份
顯示2020年5月,程式碼如下:
```dart
DateTime _selectedDate = DateTime.now();
DayPicker(
selectedDate: _selectedDate,
currentDate: DateTime.now(),
onChanged: (date) {
setState(() {
_selectedDate = date;
});
},
firstDate: DateTime(2020, 5, 1),
lastDate: DateTime(2020, 5, 31),
displayedMonth: DateTime(2020, 5),
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073650408-463644501.gif)
`selectableDayPredicate`引數定義使用者的可選日期,返回false表示不可選,例如只可選今天以前的日期:
```dart
DayPicker(
selectableDayPredicate: (date) {
return date.difference(DateTime.now()).inMilliseconds < 0;
},
...
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073650657-594345020.png)
今天以後的日期全部為灰色,不可選狀態。
## MonthPicker
可選擇的月份選擇器,在頂部有一個滾動的月份列表,每個月份下面展示當前月份的天,本質上MonthPicker是滾動的月份列表+ DayPicker,用法如下:
```dart
DateTime _selectedDate = DateTime.now();
MonthPicker(
selectedDate: _selectedDate,
onChanged: (date) {
setState(() {
_selectedDate = date;
});
},
firstDate: DateTime(2020, 1),
lastDate: DateTime(2020, 12),
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073651327-1654990834.gif)
屬性和`DayPicker`基本一致。
## YearPicker
年份選擇器,用法如下:
```dart
YearPicker(
selectedDate: _selectedDate,
onChanged: (date) {
setState(() {
_selectedDate = date;
});
},
firstDate: DateTime(2000, 1),
lastDate: DateTime(2020, 12),
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073651927-38025459.gif)
年份選擇器和月份選擇器略有不同,年份選擇器並不包含當前年份下的月份。
不管是YearPicker,還是MonthPicker、DayPicker,"我們都很少直接使用",而是使用`showDatePicker`,它會建立一個日期選擇器對話方塊。個人覺得`showDatePicker`的樣式風格不是很符合國內的審美,我們可能更多的時候是使用YearPicker、MonthPicker和DayPicker自定義日期控制元件。
## showDatePicker
`showDatePicker`並不是一個新的控制元件,而是封裝了YearPicker和MonthPicker,並進行了聯動,用法如下:
```dart
RaisedButton(
onPressed: () async {
var result = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime(2030));
print('$result');
},
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073652354-1510794466.gif)
相關引數介紹如下:
- `initialDate`初始化時間,通常情況下設定為當前時間。
- `firstDate`表示開始時間,不能選擇此時間前面的時間。
- `lastDate`表示結束時間,不能選擇此時間之後的時間。
- `showDatePicker`方法是Future方法,點選日期選擇控制元件的確定按鈕後,返回選擇的日期。
- `selectableDayPredicate`引數定義使用者的可選日期,返回false表示不可選,與DayPicker用法相同。
`builder`引數可用於包裝對話方塊視窗小部件以新增繼承的視窗小部件,例如`Theme`,設定深色主題用法如下:
```dart
showDatePicker(
builder: (context, child) {
return Theme(
data: ThemeData.dark(),
child: child,
);
},
...
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073652661-855999450.png)
上面是Material風格的日期控制元件,下面介紹下iOS風格的日期控制元件。
## CupertinoDatePicker
ios風格的日期選擇器,用法如下:
```dart
var _dateTime = DateTime.now();
CupertinoDatePicker(
initialDateTime: _dateTime,
onDateTimeChanged: (date) {
setState(() {
_dateTime = date;
});
},
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073652861-270935256.png)
`mode`引數設定日期的格式:
- time:只顯示時間,效果:`4 | 14 | PM `
- date:只顯示日期,效果:`July | 13 | 2012`
- dateAndTime:時間和日期都顯示,效果: `Fri Jul 13 | 4 | 14 | PM `
設定最大日期和最小日期:
```dart
CupertinoDatePicker(
minimumDate: DateTime.now().add(Duration(days: -1)),
maximumDate: DateTime.now().add(Duration(days: 1)),
...
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073653139-225707677.png)
使用24小時制:
```dart
CupertinoDatePicker(
use24hFormat: true,
...
)
```
## showTimePicker
時間選擇器只能通過`showTimePicker`的方式來呼叫,用法如下:
```dart
RaisedButton(
onPressed: () async {
showTimePicker(
context: context, initialTime: TimeOfDay.now());
},
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073653372-1454309535.png)
`builder`引數用於控制子控制元件,可以向DatePicker一樣設定深色主題,還可以設定其顯示24小時,用法如下:
```dart
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(alwaysUse24HourFormat: true),
child: child,
);
});
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073653576-1602902627.png)
## CupertinoTimerPicker
CupertinoTimerPicker 是ios風格的時間選擇器,基本用法如下:
```dart
CupertinoTimerPicker(
onTimerDurationChanged: (Duration duration){
},
)
```
效果如下:
![](https://img2020.cnblogs.com/other/467322/202005/467322-20200509073653827-989264446.png)
設定只顯示小時和分鐘:
```dart
CupertinoTimerPicker(
mode: CupertinoTimerPickerMode.hm,
...
)
```
預設情況下,CupertinoTimerPicker顯示0:0:0,設定顯示當前時間:
```dart
var now = DateTime.now();
return Container(
height: 200,
child: CupertinoTimerPicker(
initialTimerDuration: Duration(hours: now.hour,minutes: now.minute,seconds: now.second),
onTimerDurationChanged: (Duration duration) {},
),
);
```
## 國際化
增加國際化處理,在pubspec.yaml新增支援:
```dart
dependencies:
flutter_localizations:
sdk: flutter
```
在頂級控制元件MaterialApp新增支援,具體資訊可查[MaterialApp控制元件](http://laomengit.com/flutter/widgets/MaterialApp.html):
```dart
MaterialApp(
localeListResolutionCallback: