single_picker_field.dart 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * @Author: XianKaiQun
  3. * @Date: 2020-08-25 14:59:08
  4. * @LastEditors: ChenYaJin
  5. * @LastEditTime: 2021-11-02 09:51:15
  6. * @Description:
  7. */
  8. import 'package:flutter/material.dart';
  9. import 'package:flutter/services.dart';
  10. import 'package:wisdom_cli/wisdom_cli.dart';
  11. typedef WSinglePickerFieldBuilder<T> = Widget Function(
  12. T value,
  13. Future<void> Function() trigger,
  14. );
  15. typedef WSinglePickerGetData<T> = Future<List<T>> Function();
  16. typedef WSinglePickerFieldOnChanged<T> = void Function(T value);
  17. ///减少逻辑代码的单选组件
  18. class WSinglePickerField<T extends WPickerEntity> extends StatefulWidget {
  19. WSinglePickerField({
  20. Key? key,
  21. required this.getData,
  22. required this.builder,
  23. this.title,
  24. this.value,
  25. this.onChanged,
  26. }) : super(key: key);
  27. final WSinglePickerFieldBuilder<T?> builder;
  28. final Widget? title;
  29. final WSinglePickerGetData<T>? getData;
  30. final T? value;
  31. final WSinglePickerFieldOnChanged<T>? onChanged;
  32. @override
  33. _WSinglePickerFieldState<T> createState() => _WSinglePickerFieldState<T>();
  34. }
  35. class _WSinglePickerFieldState<T extends WPickerEntity>
  36. extends State<WSinglePickerField<T>> {
  37. T? _value;
  38. T? get value => _value;
  39. @override
  40. void initState() {
  41. super.initState();
  42. _value = widget.value;
  43. }
  44. ///触发单选弹出层
  45. Future<void> _trigger() async {
  46. final res = await WPickerUtil.single<T>(
  47. context,
  48. title: widget.title,
  49. getData: widget.getData!,
  50. initialValue: _value,
  51. );
  52. if (res != null) {
  53. _onChanged(res);
  54. }
  55. }
  56. ///触发[widget.onChanged],
  57. ///刷新视图[widget.builder]
  58. void _onChanged(T value) {
  59. if (_value == value) return;
  60. _value = value;
  61. setState(() {});
  62. if (widget.onChanged != null) {
  63. widget.onChanged!(value);
  64. }
  65. }
  66. @override
  67. Widget build(BuildContext context) {
  68. return widget.builder(value, () => _trigger());
  69. }
  70. }
  71. ///picker表单
  72. class WSinglePickerFormField<T extends WPickerEntity> extends WFormField<T?> {
  73. WSinglePickerFormField({
  74. Key? key,
  75. required WSinglePickerFieldBuilder<T?> builder,
  76. required WSinglePickerGetData<T> getData,
  77. required this.field,
  78. Widget? title,
  79. T? value,
  80. this.onChanged,
  81. FormFieldSetter<T>? onSaved,
  82. FormFieldValidator<T>? validator,
  83. AutovalidateMode? autovalidateMode,
  84. bool enabled = true,
  85. }) : super(
  86. key: key,
  87. field: field,
  88. onSaved: onSaved,
  89. validator: validator,
  90. autovalidateMode: autovalidateMode,
  91. enabled: enabled,
  92. builder: (WFormFieldState<T?> fieldState) {
  93. final _fieldState = fieldState as _WSinglePickerFormFieldState<T>;
  94. return WSinglePickerField(
  95. title: title,
  96. value: _fieldState.value,
  97. getData: getData,
  98. builder: builder,
  99. onChanged: (dynamic value) {
  100. _fieldState.didChange(value);
  101. },
  102. );
  103. },
  104. );
  105. ///直接使用[textField]进行builder
  106. WSinglePickerFormField.textField({
  107. Key? key,
  108. required WSinglePickerGetData<T> getData,
  109. required this.field,
  110. Widget? title,
  111. T? value,
  112. this.onChanged,
  113. TextEditingController? controller,
  114. FormFieldSetter<T>? onSaved,
  115. FormFieldValidator<T>? validator,
  116. AutovalidateMode? autovalidateMode,
  117. bool? enabled = true,
  118. FocusNode? focusNode,
  119. InputDecoration? decoration,
  120. TextInputType? keyboardType,
  121. TextCapitalization textCapitalization = TextCapitalization.none,
  122. TextInputAction? textInputAction,
  123. TextStyle? style,
  124. StrutStyle? strutStyle,
  125. TextDirection? textDirection,
  126. TextAlign textAlign = TextAlign.start,
  127. TextAlignVertical? textAlignVertical,
  128. bool autofocus = false,
  129. // bool readOnly = false,
  130. ToolbarOptions? toolbarOptions,
  131. bool? showCursor,
  132. String obscuringCharacter = '•',
  133. bool obscureText = false,
  134. bool autocorrect = true,
  135. SmartDashesType? smartDashesType,
  136. SmartQuotesType? smartQuotesType,
  137. bool enableSuggestions = true,
  138. MaxLengthEnforcement maxLengthEnforcement = MaxLengthEnforcement.enforced,
  139. int maxLines = 1,
  140. int? minLines,
  141. bool expands = false,
  142. int? maxLength,
  143. // GestureTapCallback onTap,
  144. VoidCallback? onEditingComplete,
  145. ValueChanged<String>? onFieldSubmitted,
  146. List<TextInputFormatter>? inputFormatters,
  147. double cursorWidth = 2.0,
  148. Radius? cursorRadius,
  149. Color? cursorColor,
  150. Brightness? keyboardAppearance,
  151. EdgeInsets scrollPadding = const EdgeInsets.all(20.0),
  152. bool enableInteractiveSelection = true,
  153. InputCounterWidgetBuilder? buildCounter,
  154. ScrollPhysics? scrollPhysics,
  155. Iterable<String>? autofillHints,
  156. }) : super(
  157. key: key,
  158. field: field,
  159. onSaved: onSaved,
  160. validator: validator,
  161. autovalidateMode: autovalidateMode,
  162. enabled: enabled ?? true,
  163. builder: (WFormFieldState<T?> fieldState) {
  164. final state = fieldState as _WSinglePickerFormFieldState<T>;
  165. //主题
  166. InputDecoration _decoration = decoration ?? InputDecoration();
  167. _decoration = _decoration.applyDefaults(
  168. Theme.of(state.context).inputDecorationTheme,
  169. );
  170. _decoration = _decoration.copyWith(
  171. suffixIconConstraints:
  172. _decoration.suffixIconConstraints ?? const BoxConstraints(),
  173. suffixIcon: _decoration.suffixIcon ??
  174. Icon(
  175. Icons.chevron_right,
  176. color: Colors.black38,
  177. ),
  178. errorText: state.errorText,
  179. );
  180. final _controller = controller ?? TextEditingController();
  181. _controller.value =
  182. _controller.value.copyWith(text: state.value?.selectName);
  183. return WSinglePickerField(
  184. title: title,
  185. getData: getData,
  186. onChanged: (dynamic value) => state.didChange(value),
  187. builder: (dynamic value, trigger) {
  188. return TextField(
  189. controller: _controller,
  190. focusNode: focusNode,
  191. decoration: _decoration,
  192. keyboardType: keyboardType,
  193. textInputAction: textInputAction,
  194. style: style,
  195. strutStyle: strutStyle,
  196. textAlign: textAlign,
  197. textAlignVertical: textAlignVertical,
  198. textDirection: textDirection,
  199. textCapitalization: textCapitalization,
  200. autofocus: autofocus,
  201. toolbarOptions: toolbarOptions,
  202. readOnly: true,
  203. showCursor: showCursor,
  204. obscuringCharacter: obscuringCharacter,
  205. obscureText: obscureText,
  206. autocorrect: autocorrect,
  207. smartDashesType: smartDashesType ??
  208. (obscureText
  209. ? SmartDashesType.disabled
  210. : SmartDashesType.enabled),
  211. smartQuotesType: smartQuotesType ??
  212. (obscureText
  213. ? SmartQuotesType.disabled
  214. : SmartQuotesType.enabled),
  215. enableSuggestions: enableSuggestions,
  216. maxLengthEnforcement: maxLengthEnforcement,
  217. maxLines: maxLines,
  218. minLines: minLines,
  219. expands: expands,
  220. maxLength: maxLength,
  221. // onChanged: onChangedHandler,
  222. onTap: () => trigger(),
  223. onEditingComplete: onEditingComplete,
  224. onSubmitted: onFieldSubmitted,
  225. inputFormatters: inputFormatters,
  226. enabled: enabled ?? true,
  227. cursorWidth: cursorWidth,
  228. cursorRadius: cursorRadius,
  229. cursorColor: cursorColor,
  230. scrollPadding: scrollPadding,
  231. scrollPhysics: scrollPhysics,
  232. keyboardAppearance: keyboardAppearance,
  233. enableInteractiveSelection: enableInteractiveSelection,
  234. buildCounter: buildCounter,
  235. autofillHints: autofillHints,
  236. );
  237. },
  238. );
  239. },
  240. );
  241. final String field;
  242. final WSinglePickerFieldOnChanged<T>? onChanged;
  243. @override
  244. _WSinglePickerFormFieldState<T> createState() =>
  245. _WSinglePickerFormFieldState<T>();
  246. }
  247. class _WSinglePickerFormFieldState<T extends WPickerEntity>
  248. extends WFormFieldState<T?> {
  249. @override
  250. WSinglePickerFormField<T> get widget =>
  251. super.widget as WSinglePickerFormField<T>;
  252. @override
  253. void didChange(T? value) {
  254. super.didChange(value);
  255. if (widget.onChanged != null) {
  256. widget.onChanged!(value!);
  257. }
  258. }
  259. }