gpt4 book ai didi

flutter - 在小部件构建期间调用setState()

转载 作者:行者123 更新时间:2023-12-03 04:58:59 26 4
gpt4 key购买 nike

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

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();
}
}


然后,在显示表单组件的小部件中,执行类似的操作。
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
}
}

如您在此处看到的,我传入了一些函数以提取用户名的值以及验证的状态,并使用它们来确定是否应启用表单处理程序小部件中的“下一个”按钮。现在,这引起了一个问题,特别是因为在重建小部件时,我传递给“小型表单”的函数会调用 initState()

我该如何处理呢?或者,是否有更好的方法可以实现更干净的多页表单?

谢谢。

最佳答案

build()应该是快速且幂等的。您不应在内部调用setState()。想象一下build()每秒被调用60次(尽管它不会由于优化而被调用),并且您将拥有正确的心态。

关于flutter - 在小部件构建期间调用setState(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59994410/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com