form.dart 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import 'package:flutter/widgets.dart';
  2. class _Scope extends InheritedWidget {
  3. _Scope({
  4. Key? key,
  5. this.formState,
  6. this.generation,
  7. required this.child,
  8. }) : super(key: key, child: child);
  9. final Widget child;
  10. final int? generation;
  11. final WFormState? formState;
  12. ///通过验证[generation]的变化进行刷新
  13. @override
  14. bool updateShouldNotify(_Scope oldWidget) =>
  15. generation != oldWidget.generation;
  16. }
  17. ///基于[Form]进行改造,实现双向绑定
  18. ///
  19. ///[WFormState.values]可获取到表单全部数据
  20. ///
  21. ///[WFormState.setValue]设置一个对应[field]的值
  22. ///
  23. ///[WFormState.mergeValues]合并[values]
  24. class WForm extends StatefulWidget {
  25. WForm({
  26. Key? key,
  27. this.child,
  28. this.autovalidateMode = AutovalidateMode.disabled,
  29. this.autoLostFocus = true,
  30. this.onWillPop,
  31. this.onChanged,
  32. this.initialValues,
  33. }) : super(key: key);
  34. static WFormState? of(BuildContext context) {
  35. final _Scope? scope = context.dependOnInheritedWidgetOfExactType<_Scope>();
  36. return scope?.formState;
  37. }
  38. ///失去焦点
  39. static void lostFocus(BuildContext context) =>
  40. FocusScope.of(context).requestFocus(
  41. FocusNode(),
  42. );
  43. final AutovalidateMode autovalidateMode;
  44. ///自动失去焦点
  45. final bool autoLostFocus;
  46. final WillPopCallback? onWillPop;
  47. final VoidCallback? onChanged;
  48. final Widget? child;
  49. final Map<String, dynamic>? initialValues;
  50. @override
  51. WFormState createState() => WFormState();
  52. }
  53. class WFormState extends State<WForm> {
  54. final _formKey = GlobalKey<FormState>();
  55. int _generation = 0;
  56. Map<String, dynamic>? _values;
  57. Map<String, dynamic>? _initialValues;
  58. @override
  59. void initState() {
  60. ///深拷贝
  61. _values = Map.from(widget.initialValues ?? {});
  62. ///深拷贝
  63. _initialValues = Map.from(widget.initialValues ?? {});
  64. super.initState();
  65. }
  66. void _initValue(String field, value) {
  67. _values![field] = value;
  68. }
  69. @override
  70. Widget build(BuildContext context) {
  71. Widget? current = widget.child;
  72. if (widget.autoLostFocus) {
  73. current = GestureDetector(
  74. behavior: HitTestBehavior.translucent,
  75. onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
  76. child: current,
  77. );
  78. }
  79. current = Form(
  80. key: _formKey,
  81. child: current!,
  82. autovalidateMode: widget.autovalidateMode,
  83. onWillPop: widget.onWillPop,
  84. onChanged: widget.onChanged,
  85. );
  86. current = _Scope(
  87. formState: this,
  88. generation: _generation,
  89. child: current,
  90. );
  91. return current;
  92. }
  93. Map<String, dynamic>? get values => _values;
  94. Map<String, dynamic> get initialValues => _initialValues ?? {};
  95. ///保存,同[FormState.save]
  96. void save() => _formKey.currentState?.save();
  97. ///初始化,同[FormState.reset]
  98. void reset() {
  99. _formKey.currentState?.reset();
  100. _generation++;
  101. }
  102. ///验证表单,同[FormState.validate]
  103. void validate() => _formKey.currentState?.validate();
  104. ///[WFormState.setValue]设置一个对应[field]的值
  105. void setValue(String field, value) {
  106. if (_values![field] != value) {
  107. _values![field] = value;
  108. _generation++;
  109. setState(() {});
  110. }
  111. }
  112. ///[WFormState.mergeValues]合并[values]
  113. void mergeValues(Map<String, dynamic> values) {
  114. final newValues = _values!..addAll(values);
  115. if (newValues != _values) {
  116. _values = newValues;
  117. _generation++;
  118. setState(() {});
  119. }
  120. }
  121. }
  122. typedef WFormFieldBuilder<T> = Widget Function(WFormFieldState<T> fieldState);
  123. ///表单项构造
  124. ///
  125. /// 与[FormField] 类似
  126. class WFormField<T> extends FormField<T> {
  127. WFormField({
  128. Key? key,
  129. required this.field,
  130. required WFormFieldBuilder<T> builder,
  131. FormFieldSetter<T>? onSaved,
  132. FormFieldValidator<T>? validator,
  133. AutovalidateMode? autovalidateMode = AutovalidateMode.disabled,
  134. bool enabled = true,
  135. }) : assert(field.isNotEmpty, 'field不能为空'),
  136. super(
  137. key: key,
  138. onSaved: onSaved,
  139. validator: validator,
  140. autovalidateMode: autovalidateMode,
  141. enabled: enabled,
  142. builder: (fieldState) =>
  143. builder((fieldState as WFormFieldState) as WFormFieldState<T>),
  144. );
  145. final String field;
  146. @override
  147. WFormFieldState<T> createState() => WFormFieldState<T>();
  148. }
  149. class WFormFieldState<T> extends FormFieldState<T> {
  150. @override
  151. WFormField<T> get widget => super.widget as WFormField<T>;
  152. @override
  153. T? get value => WForm.of(context)?.values![widget.field];
  154. T? get initialValue => WForm.of(context)?.initialValues[widget.field];
  155. String? _errorText;
  156. String? get errorText => _errorText;
  157. bool get hasError => _errorText != null;
  158. @override
  159. void setValue(T? value, {rebuild = false}) {
  160. if (widget.field != '') {
  161. if (rebuild == true) {
  162. WForm.of(context)!.setValue(widget.field, value);
  163. } else {
  164. WForm.of(context)!._initValue(widget.field, value);
  165. }
  166. }
  167. super.setValue(value);
  168. }
  169. @override
  170. void didChange(T? value) {
  171. setValue(value);
  172. super.didChange(value);
  173. }
  174. @override
  175. bool validate() {
  176. if (widget.validator != null) _errorText = widget.validator!(value);
  177. return hasError;
  178. }
  179. @override
  180. void reset() {
  181. setValue(initialValue);
  182. super.reset();
  183. }
  184. }