Flutter系統提供了一些日期選擇類組件,好比DayPicker、MonthPicker、YearPicker、showDatePicker、CupertinoDatePicker等,其中前4個爲Material風格組件,最後一個爲iOS風格組件。本文介紹了控件的基本用法及如何實現國際化,若是系統提供的國際化不知足你的須要,最後也介紹瞭如何實現自定義國際化。html
顯示給定月份的日期,並容許選擇一天。這些天以矩形網格排列,一週的每一天都有一列。ios
DayPicker有幾個必填參數,分別以下:git
顯示2020年5月,代碼以下:微信
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),
)複製代碼
效果以下:async
selectableDayPredicate
參數定義用戶的可選日期,返回false表示不可選,例如只可選今天之前的日期:ide
DayPicker(
selectableDayPredicate: (date) {
return date.difference(DateTime.now()).inMilliseconds < 0;
},
...
)複製代碼
效果以下:post
今天之後的日期所有爲灰色,不可選狀態。ui
可選擇的月份選擇器,在頂部有一個滾動的月份列表,每月份下面展現當前月份的天,本質上MonthPicker是滾動的月份列表+ DayPicker,用法以下:this
DateTime _selectedDate = DateTime.now();
MonthPicker(
selectedDate: _selectedDate,
onChanged: (date) {
setState(() {
_selectedDate = date;
});
},
firstDate: DateTime(2020, 1),
lastDate: DateTime(2020, 12),
)複製代碼
效果以下:spa
屬性和DayPicker
基本一致。
年份選擇器,用法以下:
YearPicker(
selectedDate: _selectedDate,
onChanged: (date) {
setState(() {
_selectedDate = date;
});
},
firstDate: DateTime(2000, 1),
lastDate: DateTime(2020, 12),
)複製代碼
效果以下:
年份選擇器和月份選擇器略有不一樣,年份選擇器並不包含當前年份下的月份。
無論是YearPicker,仍是MonthPicker、DayPicker,"咱們都不多直接使用",而是使用showDatePicker
,它會建立一個日期選擇器對話框。我的以爲showDatePicker
的樣式風格不是很符合國內的審美,咱們可能更多的時候是使用YearPicker、MonthPicker和DayPicker自定義日期控件。
showDatePicker
並非一個新的控件,而是封裝了YearPicker和MonthPicker,並進行了聯動,用法以下:
RaisedButton(
onPressed: () async {
var result = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime(2030));
print('$result');
},
)複製代碼
效果以下:
相關參數介紹以下:
initialDate
初始化時間,一般狀況下設置爲當前時間。
firstDate
表示開始時間,不能選擇此時間前面的時間。
lastDate
表示結束時間,不能選擇此時間以後的時間。
showDatePicker
方法是Future方法,點擊日期選擇控件的肯定按鈕後,返回選擇的日期。
selectableDayPredicate
參數定義用戶的可選日期,返回false表示不可選,與DayPicker用法相同。
builder
參數可用於包裝對話框窗口小部件以添加繼承的窗口小部件,例如Theme
,設置深色主題用法以下:
showDatePicker(
builder: (context, child) {
return Theme(
data: ThemeData.dark(),
child: child,
);
},
...
)複製代碼
效果以下:
上面是Material風格的日期控件,下面介紹下iOS風格的日期控件。
ios風格的日期選擇器,用法以下:
var _dateTime = DateTime.now();
CupertinoDatePicker(
initialDateTime: _dateTime,
onDateTimeChanged: (date) {
setState(() {
_dateTime = date;
});
},
)複製代碼
效果以下:
mode
參數設置日期的格式:
4 | 14 | PM
July | 13 | 2012
Fri Jul 13 | 4 | 14 | PM
設置最大日期和最小日期:
CupertinoDatePicker(
minimumDate: DateTime.now().add(Duration(days: -1)),
maximumDate: DateTime.now().add(Duration(days: 1)),
...
)複製代碼
效果以下:
使用24小時制:
CupertinoDatePicker(
use24hFormat: true,
...
)複製代碼
時間選擇器只能經過showTimePicker
的方式來調用,用法以下:
RaisedButton(
onPressed: () async {
showTimePicker(
context: context, initialTime: TimeOfDay.now());
},
)複製代碼
效果以下:
builder
參數用於控制子控件,能夠向DatePicker同樣設置深色主題,還能夠設置其顯示24小時,用法以下:
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(alwaysUse24HourFormat: true),
child: child,
);
});複製代碼
效果以下:
CupertinoTimerPicker 是ios風格的時間選擇器,基本用法以下:
CupertinoTimerPicker(
onTimerDurationChanged: (Duration duration){
},
)複製代碼
效果以下:
設置只顯示小時和分鐘:
CupertinoTimerPicker(
mode: CupertinoTimerPickerMode.hm,
...
)複製代碼
默認狀況下,CupertinoTimerPicker顯示0:0:0,設置顯示當前時間:
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添加支持:
dependencies:
flutter_localizations:
sdk: flutter 複製代碼
在頂級控件MaterialApp添加支持,具體信息可查MaterialApp控件:
MaterialApp(
localeListResolutionCallback:
(List<Locale> locales, Iterable<Locale> supportedLocales) {
return Locale('zh');
},
localeResolutionCallback:
(Locale locale, Iterable<Locale> supportedLocales) {
return Locale('zh');
},
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
const Locale('zh', 'CH'),
const Locale('en', 'US'),
],
...
)複製代碼
以上方式對全部日期控件都有效果,效果以下:
咱們對iOS風格的控件自定義國際化爲例,新建新的類MyLocalizationsDelegate
:
class MyLocalizationsDelegate
extends LocalizationsDelegate<CupertinoLocalizations> {
const MyLocalizationsDelegate();
@override
bool isSupported(Locale locale) => locale.languageCode == 'zh';
@override
Future<CupertinoLocalizations> load(Locale locale) =>
ZhCupertinoLocalizations.load(locale);
@override
bool shouldReload(MyLocalizationsDelegate old) => false;
@override
String toString() => 'DefaultCupertinoLocalizations.delegate(zh)';
}複製代碼
ZhCupertinoLocalizations
定義以下:
class ZhCupertinoLocalizations implements CupertinoLocalizations {
const ZhCupertinoLocalizations();
static const List<String> _shortWeekdays = <String>[
'自週一',
'自週二',
'自週三',
'自週四',
'自週五',
'自週六',
'自週日',
];
static const List<String> _shortMonths = <String>[
'1月',
'2月',
'3月',
'4月',
'5月',
'6月',
'7月',
'8月',
'9月',
'10月',
'11月',
'12月',
];
static const List<String> _months = <String>[
'1月',
'2月',
'3月',
'4月',
'5月',
'6月',
'7月',
'8月',
'9月',
'10月',
'11月',
'12月',
];
@override
String datePickerYear(int yearIndex) => yearIndex.toString();
@override
String datePickerMonth(int monthIndex) => _months[monthIndex - 1];
@override
String datePickerDayOfMonth(int dayIndex) => dayIndex.toString();
@override
String datePickerHour(int hour) => hour.toString();
@override
String datePickerHourSemanticsLabel(int hour) => hour.toString() + " o'clock";
@override
String datePickerMinute(int minute) => minute.toString().padLeft(2, '0');
@override
String datePickerMinuteSemanticsLabel(int minute) {
if (minute == 1) return '1 分';
return minute.toString() + ' 分';
}
@override
String datePickerMediumDate(DateTime date) {
return '${_shortWeekdays[date.weekday - DateTime.monday]} '
'${_shortMonths[date.month - DateTime.january]} '
'${date.day.toString().padRight(2)}';
}
@override
DatePickerDateOrder get datePickerDateOrder => DatePickerDateOrder.mdy;
@override
DatePickerDateTimeOrder get datePickerDateTimeOrder =>
DatePickerDateTimeOrder.date_time_dayPeriod;
@override
String get anteMeridiemAbbreviation => '上午';
@override
String get postMeridiemAbbreviation => '下午';
@override
String get todayLabel => '今天';
@override
String get alertDialogLabel => 'Alert';
@override
String timerPickerHour(int hour) => hour.toString();
@override
String timerPickerMinute(int minute) => minute.toString();
@override
String timerPickerSecond(int second) => second.toString();
@override
String timerPickerHourLabel(int hour) => hour == 1 ? '小時' : '小時';
@override
String timerPickerMinuteLabel(int minute) => '分.';
@override
String timerPickerSecondLabel(int second) => '秒.';
@override
String get cutButtonLabel => '剪貼';
@override
String get copyButtonLabel => '拷貝';
@override
String get pasteButtonLabel => '黏貼';
@override
String get selectAllButtonLabel => '選擇所有';
static Future<CupertinoLocalizations> load(Locale locale) {
return SynchronousFuture<CupertinoLocalizations>(
const ZhCupertinoLocalizations());
}
/// A [LocalizationsDelegate] that uses [DefaultCupertinoLocalizations.load]
/// to create an instance of this class.
static const LocalizationsDelegate<CupertinoLocalizations> delegate =
MyLocalizationsDelegate();
}複製代碼
注意開始的屬性_shortWeekdays
,這個屬性表示星期幾,故意寫成'自周x',爲了和系統的區分,在根控件MaterialApp
的localizationsDelegates
屬性中增長:ZhCupertinoLocalizations.delegate
,這個就是上面定義的國際化文件,效果以下:
注意:ZhCupertinoLocalizations.delegate
要放在GlobalCupertinoLocalizations.delegate,
的前面,系統加載順序爲從上到下。
效果以下:
老孟Flutter博客地址(近200個控件用法):laomengit.com
歡迎加入Flutter交流羣(微信:laomengit)、關注公衆號【老孟Flutter】:
![]() |
![]() |