表单组件,可以接收其下的FormField组件的变化回调,通过onWillPop拦截页面返回,通过FormState可对表单字段进行保存或校验。

相关组件

TextFormField

Form基本使用

  1. <br />【child】 : 子组件 【Widget】<br />【onChanged】 : 表单变化回调 【VoidCallback】<br />【onWillPop】 : 返回回调 【WillPopCallback】<br />![118.gif](https://cdn.nlark.com/yuque/0/2020/gif/326147/1589454998692-2dbccf6b-98ae-4b8b-ae2b-63f5335b1be4.gif#align=left&display=inline&height=1576&margin=%5Bobject%20Object%5D&name=118.gif&originHeight=1576&originWidth=810&size=2715165&status=done&style=none&width=810)
import 'package:flutter/material.dart';
class CustomForm extends StatefulWidget {
  @override
  _CustomFormState createState() => _CustomFormState();
}

class _CustomFormState extends State<CustomForm> {
  GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Form(
        onWillPop: () => _willPop(context),
        key: _formKey,
        onChanged: () {
          print('Form---onChanged');
        },
        child:
            Stack(
              alignment: Alignment.centerRight,
              children: <Widget>[
                Container(
                  width: 350,
                  child: UnconstrainedBox(
                    child: Container(
                      width: 200,
                      height: 70,
                      child: TextFormField(
                        style: TextStyle(textBaseline: TextBaseline.alphabetic),
                        decoration: InputDecoration(
                          border: OutlineInputBorder(),
                          labelText: 'username',
                        ),
                        validator: _validateUsername,
                      ),
                    ),
                  ),
                ),
                Positioned(
                    top: 0, right: 0, child: _buildSubmitButton(context)),
              ],
        ),
      ),
    );
  }

  String _validateUsername(value) {
    if (value.isEmpty) {
      return '用户名不能为空';
    }
    return null;
  }

  RaisedButton _buildSubmitButton(BuildContext context) {
    return RaisedButton(
      color: Colors.blue,
      shape: CircleBorder(
        side: BorderSide(width: 2.0, color: Color(0xFFFFDFDFDF)),
      ),
      onPressed: _onSubmit,
      child: Icon(
        Icons.check,
        color: Colors.white,
      ),
    );
  }

  _onSubmit(){
    if (_formKey.currentState.validate()) {
      FocusScope.of(context).requestFocus(FocusNode());
      Navigator.of(context).pop();
    }
  }

  Future<bool> _willPop(context) async {
    return await showDialog(
          context: context,
          builder: (context) => AlertDialog(
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.all(Radius.circular(10))),
            title: Text('提示'),
            content: Text('你确定要离开此页吗?'),
            actions: <Widget>[
              FlatButton(
                onPressed: () => Navigator.of(context).pop(true),
                child: Text('确定'),
              ),
              FlatButton(
                onPressed: () => Navigator.of(context).pop(false),
                child: Text('取消'),
              ),
            ],
          ),
        ) ??
        false;
  }
}