/* * @Author: XianKaiQun * @Date: 2020-08-25 14:59:08 * @LastEditors : WuWei * @LastEditTime : 2023-05-23 11:40:04 * @Description: */ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:wisdom_cli/wisdom_cli.dart'; ///[value]当前的每一层级已选中的项组成的[List], ///[trigger] 触发弹出弹层的函数。 typedef WInfinityPickerFieldBuilder = Widget Function( List value, Future Function() trigger, ); typedef WInfinityPickerFieldOnChanged = void Function(List? value); ///无限单选 /// ///在此高阶组件中已实现调用[WPickerUtil.infinity]与[Widget]间的调用, /// ///所以你只需要关注[builder]输出的什么Widget即可。 /// /// class WInfinityPickerField extends StatefulWidget { WInfinityPickerField({ Key? key, required this.getData, required this.isLast, required this.builder, this.title, this.value, this.onChanged, }) : super(key: key); final Future Function(List) isLast; final WInfinityPickerFieldBuilder builder; final Widget? title; ///[getData] /// ///[selects]是每一个层级中已选择的项组成的[List], ///[selects]可能是[null],也可能[List.length==0], ///所以一定要正确的将[selects]作为条件,并输出正确的[List]。 final Future> Function(List item) getData; ///初始化每一个层级中已选的项组成的[List]。 final List? value; final WInfinityPickerFieldOnChanged? onChanged; @override _WInfinityPickerFieldState createState() => _WInfinityPickerFieldState(); } class _WInfinityPickerFieldState extends State> { List? _value; List get value => _value ?? []; @override void initState() { super.initState(); _value = widget.value; } ///触发单选弹出层 Future _trigger() async { final res = await WPickerUtil.infinity( context, title: widget.title, getData: widget.getData, initialValue: _value ?? [], isLast: widget.isLast, ); if (res != null) { _onChanged(res); } } ///触发[widget.onChanged], ///刷新视图[widget.builder] void _onChanged(List? 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()); } } ///无限单选--表单项。 /// ///基于[WInfinityPickerField],和[WFormField]。 /// ///[WInfinityPickerFormField.textField], ///使用[TextField]替代了[WInfinityPickerField.builder]方法 /// class WInfinityPickerFormField extends WFormField> { WInfinityPickerFormField({ Key? key, required WInfinityPickerFieldBuilder builder, required Future> Function(List item) getData, required Future Function(List) isLast, required this.field, 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 state = fieldState as _WInfinityPickerFormFieldState; return WInfinityPickerField( title: title, isLast: isLast, value: state.value, getData: getData, builder: builder, onChanged: (value) => state.didChange(value as List?), ); }, ); ///直接使用[textField]进行builder WInfinityPickerFormField.textField({ Key? key, required String Function(List value) buildName, required Future> Function(List item) getData, required Future Function(List) isLast, required this.field, Widget? title, this.onChanged, TextEditingController? controller, FormFieldSetter>? onSaved, FormFieldValidator>? validator, AutovalidateMode autovalidateMode = AutovalidateMode.disabled, bool enabled = true, FocusNode? focusNode, InputDecoration? decoration, 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, enabled: enabled, builder: (WFormFieldState> fieldState) { final state = fieldState as _WInfinityPickerFormFieldState; //主题 InputDecoration _decoration = decoration ?? InputDecoration(); _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 WInfinityPickerField( title: title, isLast: isLast, value: state.value, getData: getData, onChanged: (value) => state.didChange(value as List?), 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 WInfinityPickerFieldOnChanged? onChanged; @override _WInfinityPickerFormFieldState createState() => _WInfinityPickerFormFieldState(); } class _WInfinityPickerFormFieldState extends WFormFieldState> { @override WInfinityPickerFormField get widget => super.widget as WInfinityPickerFormField; @override void didChange(List? value) { super.didChange(value); if (widget.onChanged != null) { widget.onChanged!(value); } } }