我想创建很多带有int值的TextFormField。如果用户将TextFormField值更改为i,则将FAB设置为visible。因此,如果用户单击FAB,则可以保存新值。但是Setstate存在问题。当用户更改TextFormField时设置其触发器OnChanged的值,并在setstate内将FAB设置为可见。使用setState时,将其TextFormFields重置为初始值。如何避免此问题?
谢谢
这是我的示例代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
bool FabVisible = false;
final List<TextEditingController> controllers = List.generate(6, (index) {
return TextEditingController();
});
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
floatingActionButton: FAB(),
body: Center(
child: MyWidget(),
),
),
),
);
}
FloatingActionButton FAB() {
return FabVisible
? FloatingActionButton(onPressed: () {}, child: Icon(Icons.save))
: null;
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
// final TextEditingController controller = TextEditingController();
// final TextEditingController controller2 = TextEditingController();
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
SingleChildScrollView(
child: Column(
children: textFields(),
),
),
],
);
}
List<TextFormField> textFields() {
List<TextFormField> trash = List();
for (int i = 0; i <= 5; i++) {
TextEditingController controller = controllers[i];
controller.value = TextEditingValue(
text: 10.toString(),
selection: TextSelection.fromPosition(
TextPosition(offset: (10.toString()).length)));
trash.add(
TextFormField(
onChanged: (txt) {
controller.value = TextEditingValue(
text: txt,
selection: TextSelection.fromPosition(
TextPosition(offset: txt.length),
));
setState(() {
FabVisible = true;
});
},
keyboardType: TextInputType.number,
inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
controller: controller,
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center,
decoration: InputDecoration.collapsed(
hintText: "",
fillColor: Colors.teal,
focusColor: Colors.yellow,
),
),
);
}
return trash;
}
}
答案 0 :(得分:0)
调用setState()
时,它将重建小部件,因此再次调用textFields()
函数。为避免这种情况,我建议利用initState()
。 initState()
仅在屏幕首次加载时被调用。
让我们看看如何使用它:
class _MyWidgetState extends State<MyWidget> {
// final TextEditingController controller = TextEditingController();
// final TextEditingController controller2 = TextEditingController();
final List<Widget> children = [];
@override
void initState() {
textFields();
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
SingleChildScrollView(
child: Column(
children: children,
),
),
],
);
}
void textFields() {
for (int i = 0; i <= 5; i++) {
TextEditingController controller = controllers[i];
controller.value = TextEditingValue(
text: "10", // same thing as 10.toString()
selection: TextSelection.fromPosition(
TextPosition(offset: ("10").length)));
children.add(
TextFormField(
onChanged: (txt) {
controller.value = TextEditingValue(
text: txt,
selection: TextSelection.fromPosition(
TextPosition(offset: txt.length),
));
setState(() {
FabVisible = true;
});
},
keyboardType: TextInputType.number,
inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
controller: controller,
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center,
decoration: InputDecoration.collapsed(
hintText: "",
fillColor: Colors.teal,
focusColor: Colors.yellow,
),
),
);
}
}
}