Flutter 在小部件生成期间调用setState()

Flutter 在小部件生成期间调用setState(),flutter,dart,Flutter,Dart,我当前项目的一个要求是多页注册表单,每个页面都执行自己的独立验证。我最终决定实现这一点的方法是将其拆分为几个较小的表单,您可以将一些函数作为参数传递进来,以便在表单验证和/或值更改运行时执行。下面是我为实现此功能而创建的一个“迷你表单”的示例。这一个收集有关用户名的信息 import "package:flutter/material.dart"; class SignUpNameForm extends StatefulWidget { final Function(String) on

我当前项目的一个要求是多页注册表单,每个页面都执行自己的独立验证。我最终决定实现这一点的方法是将其拆分为几个较小的表单,您可以将一些函数作为参数传递进来,以便在表单验证和/或值更改运行时执行。下面是我为实现此功能而创建的一个“迷你表单”的示例。这一个收集有关用户名的信息

import "package:flutter/material.dart";

class SignUpNameForm extends StatefulWidget {
  final Function(String) onFirstNameChange;
  final Function(String) onLastNameChange;
  final Function(bool) onFirstNameValidationStatusUpdate;
  final Function(bool) onLastNameValidationStatusUpdate;
  final String firstNameInitialValue;
  final String lastNameInitialValue;

  SignUpNameForm(
      {this.onFirstNameChange,
      this.onLastNameChange,
      this.onFirstNameValidationStatusUpdate,
      this.onLastNameValidationStatusUpdate,
      this.firstNameInitialValue,
      this.lastNameInitialValue});

  @override
  _SignUpNameFormState createState() => _SignUpNameFormState();
}

class _SignUpNameFormState extends State<SignUpNameForm> {
  final _formKey = GlobalKey<FormState>();
  TextEditingController _firstName;
  TextEditingController _lastName;
  bool _editedFirstNameField;
  bool _editedLastNameField;

  @override
  Widget build(BuildContext context) {

    _firstName.text = widget.firstNameInitialValue;
    _lastName.text = widget.lastNameInitialValue;

    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          TextFormField(
            controller: _firstName,
            autovalidate: true,
            decoration: InputDecoration(
              hintText: "First Name",
            ),
            keyboardType: TextInputType.text,
            onChanged: (String value) {
              _editedFirstNameField = true;
              widget.onFirstNameChange(value);
            },
            validator: (String value) {
              String error;

              if (_editedFirstNameField) {
                error = value.isEmpty ? "This field is required" : null;
                bool isValid = error == null;
                widget.onFirstNameValidationStatusUpdate(isValid);
              }

              return error;
            },
          ),
          TextFormField(
            controller: _lastName,
            autovalidate: true,
            decoration: InputDecoration(
              hintText: "Last Name",
            ),
            keyboardType: TextInputType.text,
            onChanged: (String value) {
              _editedLastNameField = true;
              widget.onLastNameChange(value);
            },
            validator: (String value) {
              String error;

              if (_editedLastNameField) {
                error = value.isEmpty ? "This field is required" : null;
                bool isValid = error == null;
                widget.onLastNameValidationStatusUpdate(isValid);
              }

              return error;
            },
          ),
        ],
      ),
    );
  }

  @override
  void initState() {
    super.initState();
    _firstName = new TextEditingController();
    _lastName = new TextEditingController();
    _editedFirstNameField = false;
    _editedLastNameField = false;
  }

  @override
  void dispose() {
    super.dispose();
    _firstName.dispose();
    _lastName.dispose();
  }
}

导入“包装:颤振/材料.省道”; 类SignUpNameForm扩展StatefulWidget{ 最终函数(字符串)onFirstNameChange; 最终函数(字符串)onLastNameChange; RSTNameValidationStatusUpdate上的最终功能(bool); 最终功能(bool)onLastNameValidationStatusUpdate; 最后一个字符串firstNameInitialValue; 最后一个字符串lastNameInitialValue; 注册名称表( {this.onFirstNameChange, 这个.onLastNameChange, 此.onFirstNameValidationStatusUpdate, 此.onLastNameValidationStatusUpdate, 这个.firstNameInitialValue, 此.lastNameInitialValue}); @凌驾 _SignUpNameFormState createState()=>_SignUpNameFormState(); } 类_SignUpNameFormState扩展状态{ final _formKey=GlobalKey(); TextEditingController _firstName; text编辑控制器_lastName; bool_编辑的firstnamefield; bool_editedLastNameField; @凌驾 小部件构建(构建上下文){ _firstName.text=widget.firstNameInitialValue; _lastName.text=widget.lastName初始值; 报税表( 键:_formKey, 子:列( crossAxisAlignment:crossAxisAlignment.start, 儿童:[ TextFormField( 控制器:_firstName, 自动验证:true, 装饰:输入装饰( hintText:“名字”, ), 键盘类型:TextInputType.text, onChanged:(字符串值){ _editedFirstNameField=true; widget.onFirstNameChange(值); }, 验证器:(字符串值){ 字符串错误; 如果(_editedFirstNameField){ error=value.isEmpty?“此字段是必需的”:null; bool isValid=error==null; onFirstNameValidationStatusUpdate(isValid); } 返回误差; }, ), TextFormField( 控制器:\ u lastName, 自动验证:true, 装饰:输入装饰( hintText:“姓氏”, ), 键盘类型:TextInputType.text, onChanged:(字符串值){ _editedLastNameField=true; widget.onLastNameChange(值); }, 验证器:(字符串值){ 字符串错误; 如果(_editedLastNameField){ error=value.isEmpty?“此字段是必需的”:null; bool isValid=error==null; widget.onLastNameValidationStatusUpdate(isValid); } 返回误差; }, ), ], ), ); } @凌驾 void initState(){ super.initState(); _firstName=新的TextEditingController(); _lastName=新的TextEditingController(); _editedFirstNameField=false; _editedLastNameField=false; } @凌驾 无效处置(){ super.dispose(); _dispose(); _dispose(); } } 然后,在我的显示表单组件的小部件中,我执行类似的操作

class _SignUpFormState extends State<SignUpForm> {

  String _firstName;
  bool _firstNameIsValid;

  String _lastName;
  bool _lastNameIsValid;


  int current;
  final maxLength = 4;
  final minLength = 0;

  @override
  Widget build(BuildContext context) {
    // create the widget
    return Container(
      child: _showFormSection(),
    );
  }

  /// Show the appropriate form section
  Widget _showFormSection() {
    Widget form;

    switch (current) {
      case 0:
        form = _showNameFormSection();
        break;
      case 1:
        form = _showEmailForm();
        break;
      case 2:
        form = _showPasswordForm();
        break;
      case 3:
        form = _showDobForm();
        break;
    }

    return form;
  }

  // shows the name section of the form.
  Widget _showNameFormSection() {
    return Container(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Container(
            child: SignUpNameForm(
              firstNameInitialValue: _firstName,
              lastNameInitialValue: _lastName,
              onFirstNameChange: (String value) {
                setState(() {
                  _firstName = value;
                });
              },
              onFirstNameValidationStatusUpdate: (bool value) {
                setState(() {
                  _firstNameIsValid = value;
                });
              },
              onLastNameChange: (String value) {
                setState(() {
                  _lastName = value;
                });
              },
              onLastNameValidationStatusUpdate: (bool value) {
                setState(() {
                  _lastNameIsValid = value;
                });
              },
            ),
          ),
          Container(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                FlatButton(
                  child: Text("Next"),
                  onPressed: (_firstNameIsValid && _lastNameIsValid)
                      ? _showNextSection
                      : null,
                ),
              ],
            ),
          )
        ],
      ),
    );
  }


  /// Shows the next section in the form
  void _showNextSection() {
    print("Current Section: " + current.toString());
    setState(() {
      if (current >= maxLength) {
        current = maxLength;
      } else {
        current++;
      }
    });
    print("Next Section: " + current.toString());
  }

  /// Show the previous section of the form
  void _showPreviousSection() {
    print("Current Section:" + current.toString());
    setState(() {
      if (current <= minLength) {
        current = minLength;
      } else {
        current--;
      }
      print("Previous Section: " + current.toString());
    });
  }

  @override
  void initState() {
    super.initState();
    current = 0;
    _firstName = "";
    _firstNameIsValid = false;
    _lastName = "";
    _lastNameIsValid = false;
    // other initializations
  }
}
class\u SignUpFormState扩展状态{
字符串_firstName;
bool_firstname有效;
字符串_lastName;
bool\u lastname有效;
电流;
最终最大长度=4;
最终最小长度=0;
@凌驾
小部件构建(构建上下文){
//创建小部件
返回容器(
子项:_showFormSection(),
);
}
///显示相应的表单部分
小部件_showFormSection(){
小部件形式;
开关(电流){
案例0:
表单=_showNameFormSection();
打破
案例1:
表单=_showEmailForm();
打破
案例2:
表单=_showPasswordForm();
打破
案例3:
form=_showdoborm();
打破
}
申报表;
}
//显示窗体的“名称”部分。
小部件_showNameFormSection(){
返回容器(
子:列(
mainAxisAlignment:mainAxisAlignment.start,
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
容器(
孩子:注册姓名表(
firstName初始值:_firstName,
lastNameInitialValue:\u lastName,
onFirstNameChange:(字符串值){
设置状态(){
_firstName=值;
});
},
onFirstNameValidationStatusUpdate:(布尔值){
设置状态(){
_firstNameIsValid=值;
});
},
onLastNameChange:(字符串值){
设置状态(){
_lastName=值;
});
},
onLastNameValidationStatusUpdate:(布尔值){
设置状态(){
_lastNameIsValid=值;
});
},
),
),
容器(
孩子:排(
mainAxisAlignment:mainAxisAlignment.end,
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
扁平按钮(
子项:文本(“下一个”),
按下时:(_firstNameIsValid&&u lastNameIsValid)
?_showNextSection
:null,
),
],
),
)
],
),
);
}
///显示窗体中的下一节
虚无