如何在字段更改后更新表单

  • 本文关键字:更新 表单 字段 flutter
  • 更新时间 :
  • 英文 :


我有一个表单,我想重新做一个计算当用户完成编辑任何字段。我以为onFieldSubmitted会这样做,但是这个从来没有被调用过。在下面的最小示例中,我希望在用户离开场地时调用recalc()函数。我知道onChange会起作用,但我不希望每次用户输入一个字符时都要重新计算,因为它有点慢,而且在我看来,看到验证错误时仍然组成字段的内容。

我正在使用Flutter 2.10.4与"Edge (web-javascript)"设备。

import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(title: 'Form demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: const Center(child: MyForm()),
);
}
}
class MyForm extends StatefulWidget {
const MyForm({Key? key}) : super(key: key);
@override
State<MyForm> createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
int _q = 0;
void recalc() {
print("Recalculate");
setState(() {
_q += 1;
});
}
@override
Widget build(BuildContext context) {
return Form(
child: Column(
children: [
TextFormField(
onFieldSubmitted: (value) {
recalc();
},
),
TextFormField(
onFieldSubmitted: (value) {
recalc();
},
),
Text('changed $_q')
],
));
}
}

编辑:我现在意识到,如果我在一个字段上按ENTER键,onFieldSubmitted就会被解雇,而不是当我tab离开它时。我在PC上使用web-javascript设备,所以我确实有一个ENTER键-不确定如果我使用Android模拟器会如何工作

如果我理解正确的话,你需要一个focusNode

第一步创建focusNode

FocusNode focusNode = FocusNode();
TextEditingController firstController = TextEditingController();

第二步发送到textformfield

TextFormField(
focusNode: focusNode,
controller: firstController,
),

和addlistener在initstate

void initState() {
focusNode.addListener(() {
if(!focusNode.hasFocus){
print(firstController.text); 
recalc();
}
});
super.initState();
}

别忘了处理

@override
void dispose() {

focusNode.dispose();
firstController.dispose();
super.dispose();
}

完整代码:

import 'package:flutter/material.dart';
import 'package:googleapis/storage/v1.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(title: 'Form demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: const Center(child: MyForm()),
);
}
}
class MyForm extends StatefulWidget {
const MyForm({Key? key}) : super(key: key);
@override
State<MyForm> createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
int _q = 0;
void recalc() {
print("Recalculate");
setState(() {
_q += 1;
});
}
//TODO: create focusnode and textcontroller 
FocusNode focusNode = FocusNode();
TextEditingController firstController = TextEditingController();
@override
void initState() {
//TODO: create a listener
focusNode.addListener(() {
if(!focusNode.hasFocus){
//TODO: You can write any function
//TODO: you can take the text
print(firstController.text); 
recalc();
}
});
super.initState();
}
@override
void dispose() {
// TODO: Dont forget to dispose
focusNode.dispose();
firstController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Form(
child: Column(
children: [
TextFormField(
focusNode: focusNode,
controller: firstController,

),
TextFormField(
//You can do for here
),
Text('changed $_q')
],
));
}
}

希望它对你有好处

您需要一个TextEditingController来控制TextField的值。更多详细信息请看这篇文章。

如果你想检测用户在没有提交的情况下未聚焦字段,你可以使用FocusNode来控制它们

final controller1 = TextEditingController(text: defaultValue);
final controller2 = TextEditingController(text: defaultValue);
int _q = 0;
void recalc() {
print("Recalculate");
setState(() {
_q += 1;
});
controller1.text = defaultValue;
controller2.text = defaultValue;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
TextFormField(
controller: controller1,
onFieldSubmitted: (value) {
recalc();
},
),
TextFormField(
controller: controller2,
onFieldSubmitted: (value) {
recalc();
},
),
Text('changed $_q')
],
),
);
}

你可以尝试这种方式,没有其他的方式用户可以到其他文本字段,它似乎!!

import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(title: 'Form demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: const Center(child: MyForm()),
);
}
}
class MyForm extends StatefulWidget {
const MyForm({Key? key}) : super(key: key);
@override
State<MyForm> createState() => _MyFormState();
}
class _MyFormState extends State<MyForm> {
int _q = 0;
void recalc() {
print("Recalculate");
setState(() {
_q += 1;
});
}
@override
Widget build(BuildContext context) {
return Form(
child: Column(
children: [
TextFormField(
onEditingComplete: ( ){
recalc();
},
),
TextFormField(
onEditingComplete: ( ){
recalc();
},
),
Text('changed $_q')
],
));
}
}

最新更新