import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:wisdom_cli/wisdom_cli.dart'; typedef WDatePickerFieldBuilder = Widget Function( DateTime? value, Future Function() trigger, ); typedef WDatePickerFieldOnChanged = void Function(DateTime? value); ///减少逻辑代码的单选组件 class WDatePickerField extends StatefulWidget { WDatePickerField({ Key? key, this.initialDate, required this.builder, this.title, this.firstDate, this.lastDate, this.onChanged, }) : super(key: key); final WDatePickerFieldBuilder builder; final Widget? title; final DateTime? firstDate; final DateTime? lastDate; final DateTime? initialDate; final WDatePickerFieldOnChanged? onChanged; @override _WDatePickerFieldState createState() => _WDatePickerFieldState(); } class _WDatePickerFieldState extends State { DateTime? _value; DateTime? get value => _value; @override void initState() { super.initState(); _value = widget.initialDate; } ///触发弹出层 Future _trigger() async { final res = await WPickerUtil.date( context, title: widget.title, initialDate: _value, firstDate: widget.firstDate, lastDate: widget.lastDate, ); if (res != null) { _onChanged(res); } } ///触发[widget.onChanged], ///刷新视图[widget.builder] void _onChanged(DateTime value) { if (_value == value) return; _value = value; setState(() {}); if (widget.onChanged != null) { widget.onChanged!(value); } } @override Widget build(BuildContext context) { return widget.builder(value, () => _trigger()); } } ///picker表单 class WDatePickerFormField extends WFormField { WDatePickerFormField({ Key? key, required WDatePickerFieldBuilder builder, required this.field, DateTime? firstDate, DateTime? lastDate, Widget? title, this.onChanged, FormFieldSetter? onSaved, FormFieldValidator? validator, AutovalidateMode? autovalidateMode = AutovalidateMode.disabled, bool? enabled = true, }) : super( key: key, field: field, onSaved: onSaved, validator: validator, autovalidateMode: autovalidateMode, enabled: enabled!, builder: (WFormFieldState fieldState) { final _fieldState = fieldState as _WDatePickerFormFieldState; return WDatePickerField( title: title, initialDate: _fieldState.value, firstDate: firstDate, lastDate: lastDate, builder: builder, onChanged: (value) { _fieldState.didChange(value); }, ); }, ); ///直接使用[textField]进行builder WDatePickerFormField.textField({ Key? key, required String Function(DateTime? value) buildName, required this.field, DateTime? firstDate, DateTime? lastDate, Widget? title, this.onChanged, TextEditingController? controller, FormFieldSetter? onSaved, FormFieldValidator? validator, bool autovalidate = false, bool enabled = true, FocusNode? focusNode, InputDecoration decoration = const InputDecoration( suffixIconConstraints: const BoxConstraints(), suffixIcon: Icon(Icons.chevron_right), ), TextInputType? keyboardType, TextCapitalization textCapitalization = TextCapitalization.none, TextInputAction? textInputAction, TextStyle? style, StrutStyle? strutStyle, TextDirection? textDirection, TextAlign textAlign = TextAlign.start, TextAlignVertical? textAlignVertical, bool autofocus = false, // bool readOnly = false, ToolbarOptions? toolbarOptions, bool? showCursor, String obscuringCharacter = '•', bool obscureText = false, bool autocorrect = true, SmartDashesType? smartDashesType, SmartQuotesType? smartQuotesType, bool enableSuggestions = true, MaxLengthEnforcement maxLengthEnforcement = MaxLengthEnforcement.enforced, int maxLines = 1, int? minLines, bool expands = false, int? maxLength, // GestureTapCallback onTap, VoidCallback? onEditingComplete, ValueChanged? onFieldSubmitted, List? inputFormatters, double cursorWidth = 2.0, Radius? cursorRadius, Color? cursorColor, Brightness? keyboardAppearance, EdgeInsets scrollPadding = const EdgeInsets.all(20.0), bool enableInteractiveSelection = true, InputCounterWidgetBuilder? buildCounter, ScrollPhysics? scrollPhysics, Iterable? autofillHints, }) : super( key: key, field: field, onSaved: onSaved, validator: validator, autovalidateMode: AutovalidateMode.disabled, enabled: enabled, builder: (WFormFieldState fieldState) { final state = fieldState as _WDatePickerFormFieldState; //主题 InputDecoration _decoration = decoration; _decoration = _decoration.applyDefaults( Theme.of(state.context).inputDecorationTheme, ); _decoration = _decoration.copyWith( suffixIconConstraints: _decoration.suffixIconConstraints ?? const BoxConstraints(), suffixIcon: _decoration.suffixIcon ?? Icon( Icons.chevron_right, color: Colors.black38, ), errorText: state.errorText, ); final _controller = controller ?? TextEditingController(); _controller.value = _controller.value.copyWith(text: buildName(state.value)); return WDatePickerField( title: title, initialDate: state.value, firstDate: firstDate, lastDate: lastDate, onChanged: (value) => state.didChange(value), builder: (value, trigger) { return TextField( controller: _controller, focusNode: focusNode, decoration: _decoration, keyboardType: keyboardType, textInputAction: textInputAction, style: style, strutStyle: strutStyle, textAlign: textAlign, textAlignVertical: textAlignVertical, textDirection: textDirection, textCapitalization: textCapitalization, autofocus: autofocus, toolbarOptions: toolbarOptions, readOnly: true, showCursor: showCursor, obscuringCharacter: obscuringCharacter, obscureText: obscureText, autocorrect: autocorrect, smartDashesType: smartDashesType ?? (obscureText ? SmartDashesType.disabled : SmartDashesType.enabled), smartQuotesType: smartQuotesType ?? (obscureText ? SmartQuotesType.disabled : SmartQuotesType.enabled), enableSuggestions: enableSuggestions, maxLengthEnforcement: maxLengthEnforcement, maxLines: maxLines, minLines: minLines, expands: expands, maxLength: maxLength, // onChanged: onChangedHandler, onTap: () => trigger(), onEditingComplete: onEditingComplete, onSubmitted: onFieldSubmitted, inputFormatters: inputFormatters, enabled: enabled, cursorWidth: cursorWidth, cursorRadius: cursorRadius, cursorColor: cursorColor, scrollPadding: scrollPadding, scrollPhysics: scrollPhysics, keyboardAppearance: keyboardAppearance, enableInteractiveSelection: enableInteractiveSelection, buildCounter: buildCounter, autofillHints: autofillHints, ); }, ); }, ); final String field; final WDatePickerFieldOnChanged? onChanged; @override _WDatePickerFormFieldState createState() => _WDatePickerFormFieldState(); } class _WDatePickerFormFieldState extends WFormFieldState { @override WDatePickerFormField get widget => super.widget as WDatePickerFormField; @override void didChange(DateTime? value) { super.didChange(value); if (widget.onChanged != null) { widget.onChanged!(value); } } }