我有一个
Form
,当填写并提交正确答案时,应该通过更改 Form
中变量 TextFormFields
的值来更改 _isAnswerCorrect
的 setState
的字体颜色,它被传递到 stateless
小部件 NumberInputField
,它是 TextFormField
的包装器。
所以,在这种情况下,有一点我实在无法理解。我问了一个类似的问题here(我想将所有问题保留在那里,但评论不允许太多空间)并且那里提出的解决方案有效,因为
Form
在每次重建时都被重新分配。
但是,如果我不允许在每次重建时重新分配
Form
(请参见下面的代码2),它就不起作用,即颜色不会改变。但是,与此同时,下面的代码1可以工作。这是为什么?为什么下面的代码 1 有效并且颜色发生了变化,而代码 2 却没有。难道它们不应该“相同”,只是以不同的方式书写吗?如果有人真的能帮助我理解这里的“为什么”,我将不胜感激。
为什么这段代码(1)有效?
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
super.key,
});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isAnswerCorrect = false;
final _formKey = GlobalKey<FormState>();
void _answerIsCorrect() {
setState(() {
print('setting state');
_isAnswerCorrect = true;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: Column(
children: [
Form(
key: _formKey,
child: Row(
children: [
Expanded(
child: NumberInputField(
isAnswerCorrect: _isAnswerCorrect,
),
),
SizedBox(width: 20),
Expanded(
child: NumberInputField(
isAnswerCorrect: _isAnswerCorrect,
),
),
SizedBox(width: 20),
Expanded(
child: NumberInputField(
isAnswerCorrect: _isAnswerCorrect,
),
),
],
),
),
SizedBox(height: 20),
ElevatedButton(
child: Text('Change Color?'),
onPressed: _answerIsCorrect,
),
],
),
),
],
),
),
);
}
}
class NumberInputField extends StatelessWidget {
final bool isAnswerCorrect;
const NumberInputField({
super.key,
required this.isAnswerCorrect,
});
@override
Widget build(BuildContext context) {
Color fontColor = Colors.blue;
if (isAnswerCorrect) {
fontColor = Colors.black;
}
return TextFormField(
style: TextStyle(color: fontColor),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: '?',
),
);
}
}
为什么这段代码(2)不起作用?
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({
super.key,
});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isAnswerCorrect = false;
bool _shouldSetFormVisible = true;
final _formKey = GlobalKey<FormState>();
Widget _form = Container();
void _answerIsCorrect() {
setState(() {
print('setting state');
_isAnswerCorrect = true;
});
}
@override
Widget build(BuildContext context) {
if (_shouldSetFormVisible) {
setState(() {
_shouldSetFormVisible = false;
});
_form = Form(
key: _formKey,
child: Row(
children: [
Expanded(
child: NumberInputField(
isAnswerCorrect: _isAnswerCorrect,
),
),
SizedBox(width: 20),
Expanded(
child: NumberInputField(
isAnswerCorrect: _isAnswerCorrect,
),
),
SizedBox(width: 20),
Expanded(
child: NumberInputField(
isAnswerCorrect: _isAnswerCorrect,
),
),
],
),
);
}
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: Column(
children: [
_form,
SizedBox(height: 20),
ElevatedButton(
child: Text('Change Color?'),
onPressed: _answerIsCorrect,
),
],
),
),
],
),
),
);
}
}
class NumberInputField extends StatelessWidget {
final bool isAnswerCorrect;
const NumberInputField({
super.key,
required this.isAnswerCorrect,
});
@override
Widget build(BuildContext context) {
Color fontColor = Colors.blue;
if (isAnswerCorrect) {
fontColor = Colors.black;
}
return TextFormField(
style: TextStyle(color: fontColor),
textAlign: TextAlign.center,
decoration: InputDecoration(
hintText: '?',
),
);
}
}
谢谢!
_shouldSetFormVisible
条件有关。在第一个构建中,您给这个变量
true
值。根据您进一步重建的情况,您的这部分代码将不会再次重新运行:_form = Form(
key: _formKey,
child: Row(
children: [
Expanded(
child: NumberInputField(
isAnswerCorrect: _isAnswerCorrect,
),
),
SizedBox(width: 20),
Expanded(
child: NumberInputField(
isAnswerCorrect: _isAnswerCorrect,
),
),
SizedBox(width: 20),
Expanded(
child: NumberInputField(
isAnswerCorrect: _isAnswerCorrect,
),
),
],
),
);
因此,您通过单击按钮来运行 setState,
_isAnswerCorrect
的值已更改为
true
,但由于 _shouldSetFormVisible
的值仍然是 false
,整个条件变为 false,因此不会运行主体代码。因此 _form
创建代码不会再次运行来获取 _isAnswerCorrect
变量的新值。我希望这个解释能让你头脑清醒。如果有任何歧义,请随时发表评论。