123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089 |
- /*
- * @Author: XianKaiQun
- * @Date: 2020-08-25 16:49:31
- * @LastEditors : WuWei
- * @LastEditTime : 2023-11-27 15:28:53
- * @Description:
- */
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:wisdom_cli/new/utils/month_picker/season_picker.dart';
- import 'package:wisdom_cli/wisdom_cli.dart';
- import 'month_picker/date_period.dart';
- import 'month_picker/month_picker.dart';
- import 'month_picker/styles/date_picker_styles.dart';
- import 'month_picker/week_picker.dart';
- import 'month_picker/year_picker.dart';
- class WPickerUtil {
- WPickerUtil._();
- ///单选
- static Future<T?> single<T extends WPickerEntity>(
- BuildContext context, {
- Widget? title,
- required WSinglePickerGetData<T> getData,
- T? initialValue,
- // List selectValue,
- bool? isSearch,
- }) {
- List<T> _value = [];
- bool _isSearch = isSearch ?? false;
- if (initialValue != null) {
- _value = List.of([initialValue]);
- }
- // if (selectValue != null) {
- // _value = selectValue;
- // }
- void onChanged(List<T>? value, bool isTap) {
- _value = value!;
- if (isTap) Navigator.pop(context, _value[0]);
- }
- return WBottomModalUtil.show<T>(
- context,
- title: title,
- plain: true,
- body: WPicker<T>(
- multiple: false,
- initialValue: _value,
- getData: getData,
- onChanged: onChanged,
- isSearch: _isSearch,
- ),
- bodyConstraints: _isSearch
- ? BoxConstraints(
- maxHeight: 450,
- minHeight: 450,
- )
- : BoxConstraints(
- maxHeight: 350,
- minHeight: 250,
- ),
- );
- }
- ///多选
- static Future<List<T>?> multiple<T extends WPickerEntity>(
- BuildContext context, {
- Widget? title,
- required WSinglePickerGetData<T>? getData,
- List<T>? initialValue = const [],
- bool? isSearch = false,
- }) {
- List<T> _value = List.of(initialValue ?? []);
- void onCancel(context) => Navigator.pop(context);
- void onConfirm(context) {
- Navigator.pop(context, _value);
- }
- bool _isSearch = isSearch ?? false;
- return WBottomModalUtil.show<List<T>?>(
- context,
- title: title,
- plain: false,
- onCancel: onCancel,
- onConfirm: onConfirm,
- body: WPicker<T>(
- multiple: true,
- initialValue: _value,
- // enableValue: enableValue,
- getData: getData,
- isSearch: _isSearch,
- onChanged: (value, _) {
- _value = value!;
- },
- ),
- bodyConstraints: _isSearch
- ? BoxConstraints(
- maxHeight: 450,
- minHeight: 450,
- )
- : BoxConstraints(
- maxHeight: 350,
- minHeight: 250,
- ),
- );
- }
- ///无限单选(级联选择)
- static Future<List<T>?> infinity<T extends WPickerEntity>(
- BuildContext context, {
- Widget? title,
- required Future<List<T>> Function(List<T> item) getData,
- ///判断是否已选择到了最后一项,跳出选择
- required Future<bool> Function(List<T>)? isLast,
- List<T> initialValue = const [],
- }) {
- List<T>? _value = List.of(initialValue);
- int index = (_value.length - 1 < 0) ? 0 : initialValue.length - 1;
- bool showFutrue = _value.length == 0;
- T? currentValue() {
- if (index >= _value.length) {
- return null;
- } else {
- return _value[index];
- }
- }
- void onCancel(context) => Navigator.pop(context);
- void onConfirm(context) {
- if (_value.length != 0) Navigator.pop(context, _value);
- }
- return WBottomModalUtil.show<List<T>>(
- context,
- title: title,
- plain: true,
- onCancel: onCancel,
- onConfirm: onConfirm,
- body: StatefulBuilder(
- builder: (BuildContext context, setState) {
- add(List<T> items, isTap) async {
- if (isTap) {
- showFutrue = true;
- if (index <= _value.length - 1) {
- _value.removeRange(index, _value.length);
- }
- index++;
- _value.add(items[0]);
- if (isLast != null && await isLast(_value) == true) {
- onConfirm(context);
- } else {
- setState(() {});
- }
- }
- }
- behind(int i) {
- index = i;
- setState(() {});
- }
- final primaryColor = Theme.of(context).primaryColor;
- Widget tab(i) {
- String text =
- (_value.length > i) ? '${_value[i].selectName}' : '请选择';
- return Wisdom.column(
- onTap: () => behind(i),
- maxWidth: 100.pt,
- mainAxisAlignment: MainAxisAlignment.center,
- padding: EdgeInsets.symmetric(horizontal: 12.5.pt),
- children: [
- Spacer(),
- Text(
- text,
- overflow: TextOverflow.ellipsis,
- style: TextStyle(
- fontSize: 15.pt,
- fontWeight: i == index ? null : FontWeight.bold,
- color: i == index ? primaryColor : null,
- ),
- ),
- Spacer(),
- SizedBox(
- height: 4.pt,
- child: (i == index)
- ? WisActiveness(
- margin: EdgeInsets.only(top: 0),
- color: primaryColor,
- )
- : null,
- ),
- ],
- );
- }
- Widget tabs() {
- return Container(
- height: 44.pt,
- margin: EdgeInsets.symmetric(horizontal: 2.5.pt),
- child: ListView(
- scrollDirection: Axis.horizontal,
- children: [
- if (showFutrue)
- for (var i = 0; i < _value.length + 1; i++) tab(i)
- else
- for (var i = 0; i < _value.length; i++) tab(i),
- ],
- ),
- );
- }
- return Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- tabs(),
- Divider(height: 1),
- WPicker<T>(
- key: UniqueKey(),
- multiple: false,
- initialValue: currentValue() == null ? [] : [currentValue()!],
- getData: () =>
- getData([for (var i = 0; i < index; i++) _value[i]]),
- onChanged: (selects, isTap) => add(selects!, isTap),
- ).asExpanded(),
- ],
- );
- },
- ),
- );
- }
- /// 级联选择-------------------------------------
- static Future<List<T>?> cascade<T extends SinglePickerEntity>(
- BuildContext context, {
- Widget? title,
- bool? isSearch,
- /// 是否多选
- bool isMulti = false,
- required List<T> data,
- required int maxLength,
- String? label,
- String? value,
- List<T>? initialValue = const [],
- }) {
- List names = initialValue != null && initialValue.length > 0
- ? initialValue.last.name!.split(',')
- : [];
- List uniques = initialValue != null && initialValue.length > 0
- ? initialValue.last.unique.toString().split(',')
- : [];
- _getValue() {
- List tempList = [];
- if (initialValue!.length > 0) {
- for (int i = 0; i < names.length; i++) {
- tempList.add(
- SinglePickerEntity(
- name: names[i],
- unique: uniques[i],
- child: null,
- ),
- );
- }
- }
- List<dynamic> _list = List.of(initialValue);
- _list.last = tempList;
- return _list;
- }
- List<dynamic> _value = isMulti == true
- ? initialValue!.length > 0
- ? _getValue()
- : []
- : List.of(initialValue ?? []);
- List<T>? curlist = data;
- String? _searchValue;
- int index = (_value.length - 1 < 0) ? 0 : initialValue!.length - 1;
- bool showFutrue = _value.length == 0;
- bool _isSearch = isSearch ?? false;
- List<T>? currentValue() {
- if (index >= _value.length) {
- return null;
- } else {
- return _value[index] is List
- ? List<T>.from((_value[index] ?? []).map(
- (item) => SinglePickerEntity(
- name: item.name,
- unique: item.unique,
- child: item.child ?? null,
- ),
- ))
- : [_value[index]];
- }
- }
- void onCancel(context) => Navigator.pop(context);
- void onConfirm(context) {
- if (_value.length != 0 && _value.length == maxLength) {
- if (isMulti == true) {
- List tempList = _value;
- String name = tempList.last.map((item) => item.name).join(',');
- String value = tempList.last.map((item) => item.unique).join(',');
- tempList.last = SinglePickerEntity(name: name, unique: value);
- tempList = List<SinglePickerEntity>.from((tempList).map(
- (item) => SinglePickerEntity(
- name: item.name,
- unique: item.unique,
- child: item.child ?? null,
- ),
- ));
- Navigator.pop(context, tempList);
- } else {
- List tempList = _value;
- tempList = List<SinglePickerEntity>.from((tempList).map(
- (item) => SinglePickerEntity(
- name: item.name,
- unique: item.unique,
- child: item.child ?? null,
- ),
- ));
- Navigator.pop(context, tempList);
- }
- }
- }
- Future<List<T>> getList() async {
- if (index == 0 || index < 0) {
- curlist = data;
- } else {
- List<T>? tempList = data;
- for (var i = 0; i < (index); i++) {
- tempList!.forEach((listitem) {
- if (listitem.unique == _value[i].unique) {
- tempList = List<T>.from((listitem.child ?? []).map(
- (item) => SinglePickerEntity(
- name: item[label],
- unique: item[value],
- child: item['child'] ?? null,
- ),
- ));
- }
- });
- }
- curlist = tempList;
- }
- return curlist!;
- }
- /// 获取当前标签列表值
- _getName() {
- List names = [];
- _value.last.forEach((element) {
- names.add(element.name);
- });
- return names.join(',');
- }
- // List<T> tempList = [];
- // listLoop(List<T> data, v, count) {
- // while (count <= maxLength) {
- // data.forEach((item) => {
- // if (count == maxLength)
- // {
- // if (item.name.indexOf(v) != -1)
- // {
- // tempList.add(item),
- // }
- // }
- // else if (item.child != null && item.child.length > 0)
- // {
- // listLoop(
- // List<SinglePickerEntity>.from((item.child ?? []).map(
- // (item) => SinglePickerEntity(
- // name: item['name'],
- // unique: item['unique'],
- // child: item['child'] ?? null,
- // ),
- // )),
- // v,
- // count + 1),
- // }
- // });
- // }
- // }
- return WBottomModalUtil.show<List<T>>(
- context,
- title: title,
- plain: isMulti == true ? false : true,
- onCancel: onCancel,
- onConfirm: onConfirm,
- body: StatefulBuilder(
- builder: (BuildContext context, setState) {
- add(List<T> items, isTap) async {
- if (isTap) {
- showFutrue = true;
- if (index <= _value.length - 1) {
- _value.removeRange(index, _value.length);
- }
- if (index == (maxLength - 1)) {
- if (isMulti == true) {
- if (_value.length >= maxLength) {
- _value.last = items;
- } else {
- _value.add(items);
- }
- } else {
- _value.add(items[0]);
- onConfirm(context);
- }
- } else {
- index++;
- _value.add(items[0]);
- setState(() {});
- }
- }
- }
- behind(int i) {
- index = i;
- setState(() {});
- }
- final primaryColor = Theme.of(context).primaryColor;
- Widget tab(i) {
- String text = (_value.length > i)
- ? '${_value[i] is List ? _getName() : _value[i].selectName}'
- : '请选择';
- return Wisdom.column(
- onTap: () => behind(i),
- maxWidth: 100.pt,
- mainAxisAlignment: MainAxisAlignment.center,
- padding: EdgeInsets.symmetric(horizontal: 12.5.pt),
- children: [
- Spacer(),
- Text(
- text,
- overflow: TextOverflow.ellipsis,
- style: TextStyle(
- fontSize: 15.pt,
- fontWeight: i == index ? null : FontWeight.bold,
- color: i == index ? primaryColor : null,
- ),
- ),
- Spacer(),
- SizedBox(
- height: 4.pt,
- child: (i == index)
- ? WisActiveness(
- margin: EdgeInsets.only(top: 0),
- color: primaryColor,
- )
- : null,
- ),
- ],
- );
- }
- Widget tabs() {
- return Container(
- height: 44.pt,
- margin: EdgeInsets.symmetric(horizontal: 2.5.pt),
- child: ListView(
- scrollDirection: Axis.horizontal,
- children: [
- if (showFutrue) ...[
- for (var i = 0; i < _value.length + 1; i++)
- if (i < maxLength) ...[tab(i)],
- ] else ...[
- for (var i = 0; i < _value.length; i++)
- if (i < maxLength) ...[tab(i)],
- ],
- ],
- ),
- );
- }
- Future<List<SinglePickerEntity>?> getSearchList() async {
- if (_searchValue == null || _searchValue == '') {
- return curlist;
- } else {
- List<SinglePickerEntity> temp = [];
- data.forEach((element1) {
- if (element1.child != null && element1.child!.length > 0) {
- element1.child!.forEach((element2) {
- if (element2['child'] != null &&
- element2['child'].length > 0) {
- element2['child'].forEach((element3) {
- if (element3['name'].indexOf(_searchValue) != -1) {
- temp.add(SinglePickerEntity(
- name: element3['name'],
- unique: element3['unique'],
- cascade: [
- SinglePickerEntity(
- name: element1.name,
- unique: element1.unique,
- cascade: [],
- child: element1.child,
- ),
- SinglePickerEntity(
- name: element2['name'],
- unique: element2['unique'],
- cascade: [],
- child: element2['child'],
- )
- ],
- child: null,
- ));
- }
- });
- }
- });
- }
- });
- return temp;
- }
- }
- return Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- WSearch(
- hintText: '输入关键词搜索',
- onSubmitted: (v) => {
- _searchValue = v,
- setState(() {}),
- },
- moonlight: false,
- padding: EdgeInsets.symmetric(vertical: 10.pt),
- isDark: true,
- backColor: Colors.white,
- ),
- if (_searchValue == null || _searchValue == '') ...[
- tabs(),
- ],
- Divider(height: 1),
- WPicker<T>(
- key: UniqueKey(),
- multiple: isMulti == true,
- isSearch: false,
- initialValue: currentValue() ?? [],
- getData: () => getList(),
- onChanged: (selects, isTap) => add(selects!, isTap),
- ).asExpanded(),
- ],
- );
- },
- ),
- bodyConstraints: _isSearch
- ? BoxConstraints(
- maxHeight: 450,
- minHeight: 450,
- )
- : BoxConstraints(
- maxHeight: 350,
- minHeight: 250,
- ),
- );
- }
- /// 树-------------------------------------
- /// 级联
- static Future<List<T>?> tree<T extends WPickerEntity>(
- BuildContext context, {
- Widget? title,
- required List data,
- required String label,
- required String value,
- required String child,
- required String firstName,
- required String firstValue,
- bool? isSearch,
- /// 是否多选
- bool? isMulti,
- List? initialValue = const [],
- }) {
- List _value = List.of(initialValue ?? []);
- List<SinglePickerEntity> _selectValue = [];
- bool _isSearch = isSearch ?? false;
- void onCancel(context) => Navigator.pop(context);
- void onConfirm(context) {
- Navigator.pop(context, _selectValue);
- }
- void onChanged(List values) {
- _value = values;
- _selectValue = [];
- _value.forEach((item) {
- _selectValue
- .add(SinglePickerEntity(name: item[label], unique: item[value]));
- });
- if (isMulti != null && isMulti == false) {
- Navigator.pop(
- context,
- _selectValue.length == 0
- ? null
- : _selectValue,
- );
- }
- }
- return WBottomModalUtil.show<List<T>>(
- context,
- title: title,
- plain: false,
- onCancel: onCancel,
- onConfirm: onConfirm,
- body: WTreePicker<T>(
- key: UniqueKey(),
- labelname: label,
- valuename: value,
- childname: child,
- firstName: firstName,
- firstValue: firstValue,
- multiple: isMulti ?? false,
- isSearch: isSearch ?? false,
- initialValue: initialValue,
- data: data,
- onChanged: (value, _) => onChanged(value),
- ),
- bodyConstraints: _isSearch
- ? BoxConstraints(
- maxHeight: 400,
- minHeight: 400,
- )
- : BoxConstraints(
- maxHeight: 350,
- minHeight: 250,
- ),
- );
- }
- /// 周选择
- static Future<DatePeriod?> week(
- BuildContext context, {
- Widget? title,
- DateTime? firstDate,
- DateTime? lastDate,
- DatePeriod? initialDate,
- }) {
- final _firstDate = firstDate ?? DateTime(2015);
- final _lastDate = firstDate ?? DateTime(2100);
- final now = DateTime.now().toLocal();
- DatePeriod _value = initialDate ??
- DatePeriod(
- DateTime(now.year, now.month, now.day),
- DateTime(now.year, now.month, now.day + 1),
- );
- return WBottomModalUtil.show<DatePeriod?>(
- context,
- title: title,
- plain: false,
- onCancel: (_) => Navigator.pop(context),
- onConfirm: (_) => Navigator.pop(context, _value),
- body: StatefulBuilder(
- builder: (BuildContext context, setState) {
- return UtilWeekPicker(
- firstDate: _firstDate,
- lastDate: _lastDate,
- selectedDate: _value.start,
- onChanged: (DatePeriod value) {
- _value = value;
- setState(() {});
- },
- datePickerStyles: DatePickerRangeStyles(firstDayOfWeekIndexs: 1),
- );
- },
- ),
- );
- }
- ///月份选择
- ///
- static Future<DateTime?> month(
- BuildContext context, {
- Widget? title,
- DateTime? firstDate,
- DateTime? lastDate,
- DateTime? initialDate,
- DatePickerStyles? datePickerStyles,
- }) {
- final _firstDate = firstDate ?? DateTime(2015);
- final now = DateTime.now().toLocal();
- DateTime _value = initialDate ?? DateTime(now.year, now.month);
- DateTime _lastDate = lastDate ?? DateTime(2100);
- return WBottomModalUtil.show<DateTime?>(
- context,
- title: title,
- plain: false,
- onCancel: (_) => Navigator.pop(context),
- onConfirm: (_) => Navigator.pop(context, _value),
- body: StatefulBuilder(
- builder: (BuildContext context, setState) {
- return WMonthPicker.single(
- datePickerStyles: datePickerStyles,
- firstDate: _firstDate,
- lastDate: _lastDate,
- selectedDate: _value,
- onChanged: (value) => {
- _value = value,
- setState(() {}),
- });
- },
- ),
- );
- }
- static Future<DateTime?> monthRange(
- BuildContext context, {
- Widget? title,
- DateTime? firstDate,
- DateTime? lastDate,
- List<DateTime>? initialDate,
- }) {
- final _firstDate = firstDate ?? DateTime(2015);
- // final now = DateTime.now().toLocal();
- List<DateTime> _value = initialDate ?? [DateTime.now(), DateTime.now()];
- DateTime _lastDate = lastDate ?? DateTime(2100);
- return WBottomModalUtil.show<DateTime?>(
- context,
- title: title,
- plain: false,
- onCancel: (_) => Navigator.pop(context),
- onConfirm: (_) => Navigator.pop(context, _value),
- body: StatefulBuilder(
- builder: (BuildContext context, setState) {
- return WMonthPicker.multi(
- firstDate: _firstDate,
- lastDate: _lastDate,
- selectedDates: _value,
- onChanged: (value) => {
- _value = value,
- setState(() {}),
- });
- },
- ),
- );
- }
- //年份选择
- ///
- static Future<DateTime?> year(
- BuildContext context, {
- Widget? title,
- DateTime? firstDate,
- DateTime? lastDate,
- DateTime? initialDate,
- }) {
- final _firstDate = firstDate ?? DateTime(2015);
- final now = DateTime.now().toLocal();
- DateTime _value = initialDate ?? DateTime(now.year, now.month);
- DateTime _lastDate = lastDate ?? DateTime(2100);
- return WBottomModalUtil.show<DateTime?>(
- context,
- title: title,
- plain: false,
- onCancel: (_) => Navigator.pop(context),
- onConfirm: (_) => Navigator.pop(context, _value),
- body: StatefulBuilder(
- builder: (BuildContext context, setState) {
- return UtilYearPicker.single(
- firstDate: _firstDate,
- lastDate: _lastDate,
- selectedDate: _value,
- onChanged: (DateTime value) {
- _value = value;
- setState(() {});
- },
- );
- },
- ),
- );
- }
- /// 季度选择
- static Future<DateTime?> season(
- BuildContext context, {
- Widget? title,
- DateTime? firstDate,
- DateTime? lastDate,
- DateTime? initialDate,
- }) {
- final _firstDate = firstDate ?? DateTime(2015);
- final now = DateTime.now().toLocal();
- DateTime _value = initialDate ?? DateTime(now.year, now.month);
- DateTime _lastDate = lastDate ?? DateTime(2100);
- return WBottomModalUtil.show<DateTime>(
- context,
- title: title,
- plain: false,
- onCancel: (_) => Navigator.pop(context),
- onConfirm: (_) => Navigator.pop(context, _value),
- body: StatefulBuilder(
- builder: (BuildContext context, setState) {
- return UtilSeasonPicker.single(
- firstDate: _firstDate,
- lastDate: _lastDate,
- selectedDate: _value,
- onChanged: (DateTime value) {
- _value = value;
- setState(() {});
- },
- );
- },
- ),
- );
- }
- ///日期选择
- ///
- static Future<DateTime?> date(
- BuildContext context, {
- Widget? title,
- DateTime? firstDate,
- DateTime? lastDate,
- DateTime? initialDate,
- }) {
- final _firstDate = firstDate ?? DateTime(2015);
- final now = DateTime.now().toLocal();
- DateTime _value = initialDate ?? DateTime(now.year, now.month, now.day);
- if (firstDate != null && lastDate == null) {
- _value = initialDate ?? firstDate.add(Duration(seconds: 1));
- }
- if (lastDate != null && firstDate == null) {
- _value = initialDate ?? lastDate.add(Duration(seconds: -1));
- }
- if (lastDate != null && firstDate != null) {
- _value = (now.difference(_firstDate).inMilliseconds > 0) &&
- (now.difference(lastDate).inMilliseconds < 0)
- ? now
- : (now.difference(_firstDate).inMilliseconds.abs() <
- now.difference(lastDate).inMilliseconds.abs())
- ? initialDate ?? firstDate
- : initialDate ?? lastDate;
- }
- DateTime _lastDate =
- lastDate ?? DateTime(now.year + 50, now.month, now.day);
- return WBottomModalUtil.show<DateTime?>(
- context,
- title: title,
- plain: true,
- onCancel: (_) => Navigator.pop(context),
- onConfirm: (_) => Navigator.pop(context, _value),
- body: CalendarDatePicker(
- initialDate: _value,
- firstDate: _firstDate,
- lastDate: _lastDate,
- onDateChanged: (value) {
- _value = value.toLocal();
- Navigator.pop(context, _value);
- },
- ),
- );
- }
- ///时间日期选择
- ///
- static Future<DateTime?> dateAndTime(
- BuildContext context, {
- Widget? title,
- DateTime? firstDate,
- DateTime? lastDate,
- DateTime? initialDate,
- ///分钟间隔,
- ///
- ///如若设置此参数之后,
- ///`firstDate`、`lastDate`、`initialDate`的minute(分钟)必须都要可整除此参数
- int minuteInterval = 1,
- }) {
- final _firstDate = firstDate ?? DateTime(2015);
- final now = DateTime.now().toLocal();
- final now2 = DateTime(
- now.year,
- now.month,
- now.day,
- now.hour,
- now.minute % minuteInterval < minuteInterval
- ? (now.minute - (now.minute % minuteInterval)) + minuteInterval
- : now.minute); //转换一下,去掉秒、微秒等
- DateTime _value = initialDate ?? now2;
- DateTime _lastDate = lastDate ??
- DateTime(
- now.year + 50,
- now.month,
- now.day,
- now.hour,
- minuteInterval == 5 && now.minute % 5 < 5
- ? now.minute - (now.minute % 5)
- : now.minute); //转换一下,去掉秒、微秒等;
- ///设置日期
- void setDate(DateTime dateTime) {
- _value = DateTime(
- dateTime.year,
- dateTime.month,
- dateTime.day,
- _value.hour,
- _value.minute,
- );
- }
- ///设置时间
- void setTime(DateTime dateTime) {
- _value = DateTime(
- _value.year,
- _value.month,
- _value.day,
- dateTime.hour,
- dateTime.minute,
- );
- }
- int indexedStack = 0;
- StateSetter? setstate1;
- StateSetter? setstate2;
- return WBottomModalUtil.show<DateTime>(
- context,
- title: StatefulBuilder(builder: (_, s) {
- final primaryColor = Theme.of(context).primaryColor;
- setstate1 = s;
- return Row(
- children: [
- Wisdom(
- onTap: () {
- indexedStack = 0;
- setstate1!(() {});
- setstate2!(() {});
- },
- padding: EdgeInsets.all(5.pt),
- child: Text(
- _value.toFormat(WisDateTimeFormat.date),
- style: TextStyle(
- color: indexedStack == 0 ? primaryColor : null,
- ),
- ),
- ),
- SizedBox(width: 5.pt),
- Wisdom(
- onTap: () {
- indexedStack = 1;
- setstate1!(() {});
- setstate2!(() {});
- },
- padding: EdgeInsets.all(5.pt),
- child: Text(
- _value.toFormat('{hh}:{mm}'),
- style: TextStyle(
- color: indexedStack == 1 ? primaryColor : null,
- ),
- ),
- ),
- ],
- );
- }),
- plain: false,
- onCancel: null,
- onConfirm: (_) => Navigator.pop(context, _value),
- body: StatefulBuilder(
- builder: (_, s) {
- setstate2 = s;
- return IndexedStack(
- index: indexedStack,
- children: [
- CalendarDatePicker(
- initialDate: _value,
- firstDate: _firstDate,
- lastDate: _lastDate,
- onDateChanged: (datetime) {
- setDate(datetime);
- indexedStack = 1;
- setstate1!(() {});
- setstate2!(() {});
- },
- ),
- CupertinoDatePicker(
- mode: CupertinoDatePickerMode.time,
- use24hFormat: true,
- minimumDate: '${_value.year}${_value.month}${_value.day}' ==
- '${_firstDate.year}${_firstDate.month}${_firstDate.day}'
- ? _firstDate
- : null,
- minuteInterval: minuteInterval,
- initialDateTime: _value,
- onDateTimeChanged: (datetime) {
- setTime(datetime);
- setstate1!(() {});
- setstate2!(() {});
- },
- )
- ],
- );
- },
- ),
- );
- }
- /// 选择时间
- static Future<DateTime?> time(
- BuildContext context, {
- Widget? title,
- DateTime? initialDate,
- ///分钟间隔,
- ///
- ///如若设置此参数之后,
- ///`firstDate`、`lastDate`、`initialDate`的minute(分钟)必须都要可整除此参数
- int minuteInterval = 1,
- }) {
- final now = DateTime.now().toLocal();
- final now2 = DateTime(
- now.year,
- now.month,
- now.day,
- now.hour,
- minuteInterval == 5 && now.minute % 5 < 5
- ? now.minute - (now.minute % 5)
- : now.minute); //转换一下,去掉秒、微秒等
- DateTime _value = initialDate ?? now2;
- ///设置时间
- void setTime(DateTime dateTime) {
- _value = DateTime(
- _value.year,
- _value.month,
- _value.day,
- dateTime.hour,
- dateTime.minute,
- );
- }
- StateSetter? setstate1;
- return WBottomModalUtil.show<DateTime>(
- context,
- title: StatefulBuilder(builder: (_, s) {
- final primaryColor = Theme.of(context).primaryColor;
- setstate1 = s;
- return Text(
- _value.toFormat('{hh}:{mm}'),
- style: TextStyle(
- color: primaryColor,
- ),
- );
- }),
- plain: false,
- onCancel: null,
- onConfirm: (_) => Navigator.pop(context, _value),
- body: StatefulBuilder(
- builder: (_, s) {
- return CupertinoDatePicker(
- mode: CupertinoDatePickerMode.time,
- use24hFormat: true,
- minuteInterval: minuteInterval,
- initialDateTime: _value,
- onDateTimeChanged: (datetime) {
- setTime(datetime);
- setstate1!(() {});
- },
- );
- },
- ),
- );
- }
- }
|