123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- import 'package:flutter/widgets.dart';
- class _Scope extends InheritedWidget {
- _Scope({
- Key? key,
- this.formState,
- this.generation,
- required this.child,
- }) : super(key: key, child: child);
- final Widget child;
- final int? generation;
- final WFormState? formState;
- ///通过验证[generation]的变化进行刷新
- @override
- bool updateShouldNotify(_Scope oldWidget) =>
- generation != oldWidget.generation;
- }
- ///基于[Form]进行改造,实现双向绑定
- ///
- ///[WFormState.values]可获取到表单全部数据
- ///
- ///[WFormState.setValue]设置一个对应[field]的值
- ///
- ///[WFormState.mergeValues]合并[values]
- class WForm extends StatefulWidget {
- WForm({
- Key? key,
- this.child,
- this.autovalidateMode = AutovalidateMode.disabled,
- this.autoLostFocus = true,
- this.onWillPop,
- this.onChanged,
- this.initialValues,
- }) : super(key: key);
- static WFormState? of(BuildContext context) {
- final _Scope? scope = context.dependOnInheritedWidgetOfExactType<_Scope>();
- return scope?.formState;
- }
- ///失去焦点
- static void lostFocus(BuildContext context) =>
- FocusScope.of(context).requestFocus(
- FocusNode(),
- );
- final AutovalidateMode autovalidateMode;
- ///自动失去焦点
- final bool autoLostFocus;
- final WillPopCallback? onWillPop;
- final VoidCallback? onChanged;
- final Widget? child;
- final Map<String, dynamic>? initialValues;
- @override
- WFormState createState() => WFormState();
- }
- class WFormState extends State<WForm> {
- final _formKey = GlobalKey<FormState>();
- int _generation = 0;
- Map<String, dynamic>? _values;
- Map<String, dynamic>? _initialValues;
- @override
- void initState() {
- ///深拷贝
- _values = Map.from(widget.initialValues ?? {});
- ///深拷贝
- _initialValues = Map.from(widget.initialValues ?? {});
- super.initState();
- }
- void _initValue(String field, value) {
- _values![field] = value;
- }
- @override
- Widget build(BuildContext context) {
- Widget? current = widget.child;
- if (widget.autoLostFocus) {
- current = GestureDetector(
- behavior: HitTestBehavior.translucent,
- onTap: () => FocusScope.of(context).requestFocus(FocusNode()),
- child: current,
- );
- }
- current = Form(
- key: _formKey,
- child: current!,
- autovalidateMode: widget.autovalidateMode,
- onWillPop: widget.onWillPop,
- onChanged: widget.onChanged,
- );
- current = _Scope(
- formState: this,
- generation: _generation,
- child: current,
- );
- return current;
- }
- Map<String, dynamic>? get values => _values;
- Map<String, dynamic> get initialValues => _initialValues ?? {};
- ///保存,同[FormState.save]
- void save() => _formKey.currentState?.save();
- ///初始化,同[FormState.reset]
- void reset() {
- _formKey.currentState?.reset();
- _generation++;
- }
- ///验证表单,同[FormState.validate]
- void validate() => _formKey.currentState?.validate();
- ///[WFormState.setValue]设置一个对应[field]的值
- void setValue(String field, value) {
- if (_values![field] != value) {
- _values![field] = value;
- _generation++;
- setState(() {});
- }
- }
- ///[WFormState.mergeValues]合并[values]
- void mergeValues(Map<String, dynamic> values) {
- final newValues = _values!..addAll(values);
- if (newValues != _values) {
- _values = newValues;
- _generation++;
- setState(() {});
- }
- }
- }
- typedef WFormFieldBuilder<T> = Widget Function(WFormFieldState<T> fieldState);
- ///表单项构造
- ///
- /// 与[FormField] 类似
- class WFormField<T> extends FormField<T> {
- WFormField({
- Key? key,
- required this.field,
- required WFormFieldBuilder<T> builder,
- FormFieldSetter<T>? onSaved,
- FormFieldValidator<T>? validator,
- AutovalidateMode? autovalidateMode = AutovalidateMode.disabled,
- bool enabled = true,
- }) : assert(field.isNotEmpty, 'field不能为空'),
- super(
- key: key,
- onSaved: onSaved,
- validator: validator,
- autovalidateMode: autovalidateMode,
- enabled: enabled,
- builder: (fieldState) =>
- builder((fieldState as WFormFieldState) as WFormFieldState<T>),
- );
- final String field;
- @override
- WFormFieldState<T> createState() => WFormFieldState<T>();
- }
- class WFormFieldState<T> extends FormFieldState<T> {
- @override
- WFormField<T> get widget => super.widget as WFormField<T>;
- @override
- T? get value => WForm.of(context)?.values![widget.field];
- T? get initialValue => WForm.of(context)?.initialValues[widget.field];
- String? _errorText;
- String? get errorText => _errorText;
- bool get hasError => _errorText != null;
- @override
- void setValue(T? value, {rebuild = false}) {
- if (widget.field != '') {
- if (rebuild == true) {
- WForm.of(context)!.setValue(widget.field, value);
- } else {
- WForm.of(context)!._initValue(widget.field, value);
- }
- }
- super.setValue(value);
- }
- @override
- void didChange(T? value) {
- setValue(value);
- super.didChange(value);
- }
- @override
- bool validate() {
- if (widget.validator != null) _errorText = widget.validator!(value);
- return hasError;
- }
- @override
- void reset() {
- setValue(initialValue);
- super.reset();
- }
- }
|