英文:
Flutter: Dynamically Updating TextField Values Based on User Input
问题
我目前正在开发我的Flutter应用程序,并在实现特定功能方面遇到了困难。目标是在一个包含三个文本字段的页面上,一旦填充了其中任意两个文本字段,就自动填充并禁用第三个文本字段。此外,当至少一个已填充的文本字段被清除时,应重新启用已禁用的文本字段。
用示例说明:
在第一种情况下,当在第一个和第二个字段中输入数据后,第三个字段应该变为禁用状态,其值应为第一个和第二个字段中输入的值的乘积。因此,每当在第一个或第二个字段中输入内容时,第三个字段的值应相应更新。
在另一种情况下,如果在第一个和第三个字段中输入数据,第二个字段应该被禁用,并且其值应该自动更新。同样,当在第二个和第三个字段中输入内容时,我希望第一个字段表现出相同的行为。
我尝试使用TextEditingController和TextField的onChanged函数创建一个函数,但未能成功实现对TextField值的连续更新。因此,我非常感谢在这个问题上的任何帮助。
提前感谢您的支持。
英文:
I am currently working on my Flutter application and I am encountering difficulties in achieving a specific functionality. The objective is to automatically populate and disable the third TextField on a page that consists of three TextFields, once any two of the TextFields have been filled. Additionally, when at least one of the filled TextFields is cleared, the disabled TextField should be re-enabled.
To illustrate with examples:
In the first scenario, upon entering data in both the first and second fields, the third field should become disabled, and its value should be the product of the values entered in the first and second fields. Consequently, whenever input is entered in either the first or second field, the value of the third field should be updated accordingly.
In another scenario, if data is entered in the first and third fields, the second field should be disabled and its value should be updated automatically. Similarly, I would like the first field to exhibit the same behavior when input is entered in the second and third fields.
I attempted to create a function utilizing the TextEditingController and the onChanged function of the TextField, but I have been unsuccessful in achieving continuous updates to the TextField value. Therefore, I would greatly appreciate any assistance in this matter.
Thank you in advance for your support.
答案1
得分: 1
为每个文本字段设置一个控制器,在第一个字段的onChanged方法中检查第二个文本字段是否为空,如果不为空,则禁用第三个字段并进行计算,如果为空且第三个文本字段不为空,则禁用第二个字段并进行计算。
按照顺序在所有三个文本字段上重复此方法,然后使用这个思路处理空数据并清除数据,通过这种方法可以实现你想要的功能。
英文:
set a controller for every textfield
in the first field onChanged method check if the second textfield is not empty if not disable the third and do your calculation and if it was empty and the third textfield in not empty disable the second and do your calculation
repeat this approach on all the three textfields according to the order and then handle the empty and clear data with this idea you can achieve what you want
答案2
得分: 1
你可以使用 TextEditingController
和标志变量的组合来实现你需要的功能。还有许多其他方法。下面我添加了一个可工作的示例实现。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MathScreen(),
);
}
}
class MathScreen extends StatefulWidget {
const MathScreen({super.key});
@override
State<MathScreen> createState() => _MathScreenState();
}
class _MathScreenState extends State<MathScreen> {
bool t1 = true;
bool t2 = true;
bool t3 = true;
TextEditingController t1Controller = TextEditingController();
TextEditingController t2Controller = TextEditingController();
TextEditingController t3Controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Row(
children: [
Expanded(
child: TextField(
enabled: t1,
keyboardType: TextInputType.number,
controller: t1Controller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
filled: true,
hintStyle: TextStyle(
color: Colors.grey[800],
),
hintText: "",
label: Text("Amount"),
fillColor: Colors.white70,
),
onChanged: (value) {
if ((t3Controller.text == "" || !t3) &&
(t2Controller.text != "")) {
setState(() {
t3 = false;
t1 = true;
t2 = true;
t3Controller.text = value == ""
? ""
: (num.parse(value) *
num.parse(t2Controller.text))
.toString();
});
}
if (t3Controller.text != "" &&
(t2Controller.text == "" || !t2)) {
setState(() {
t2 = false;
t1 = true;
t3 = true;
t2Controller.text = value == ""
? ""
: (num.parse(t3Controller.text) /
num.parse(value))
.toString();
});
}
if (t2Controller.text == "" &&
t1Controller.text == "" &&
t3Controller.text == "") {
setState(() {
t2 = true;
t1 = true;
t3 = true;
});
}
},
),
),
Text(" X "),
Expanded(
child: TextField(
enabled: t2,
keyboardType: TextInputType.number,
controller: t2Controller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
filled: true,
hintStyle: TextStyle(
color: Colors.grey[800],
),
hintText: "",
label: Text("Unit Price"),
fillColor: Colors.white70,
),
onChanged: (value) {
if ((t1Controller.text == "" || !t1) &&
(t3Controller.text != "")) {
setState(() {
t1 = false;
t2 = true;
t3 = true;
t1Controller.text = value == ""
? ""
: (num.parse(t3Controller.text) /
num.parse(value))
.toString();
});
}
if (t1Controller.text != "" &&
(t3Controller.text == "" || !t3)) {
setState(() {
t3 = false;
t1 = true;
t2 = true;
t3Controller.text = value == ""
? ""
: (num.parse(value) *
num.parse(t1Controller.text))
.toString();
});
}
if (t2Controller.text == "" &&
t1Controller.text == "" &&
t3Controller.text == "") {
setState(() {
t2 = true;
t1 = true;
t3 = true;
});
}
},
),
),
Text(" = "),
Expanded(
child: TextField(
enabled: t3,
keyboardType: TextInputType.number,
controller: t3Controller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
filled: true,
hintStyle: TextStyle(
color: Colors.grey[800],
),
hintText: "",
label: Text("Total Price"),
fillColor: Colors.white70,
),
onChanged: (value) {
if ((t1Controller.text == "" || !t1) &&
(t2Controller.text != "")) {
setState(() {
t1 = false;
t3 = true;
t2 = true;
t1Controller.text = value == ""
? ""
: (num.parse(value) /
num.parse(t2Controller.text))
.toString();
});
}
if (t1Controller.text != "" &&
(t2Controller.text == "" || !t2)) {
setState(() {
t2 = false;
t1 = true;
t3 = true;
t2Controller.text = value == ""
? ""
: (num.parse(value) /
num.parse(t1Controller.text))
.toString();
});
}
if (t2Controller.text == "" &&
t1Controller.text == "" &&
t3Controller.text == "") {
setState(() {
t2 = true;
t1 = true;
t3 = true;
});
}
},
),
),
],
),
),
ElevatedButton(
onPressed: () {
setState(() {
t2 = true;
t1 = true;
t3 = true;
t2Controller.text = "";
t1Controller.text = "";
t3Controller.text = "";
});
},
child: Text("Reset"),
),
],
),
),
),
);
}
}
英文:
You can use TextEditingController
and flag var combination to achieve what you need. there are so many other ways too. below i added working example implementation.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MathScreen(),
);
}
}
class MathScreen extends StatefulWidget {
const MathScreen({super.key});
@override
State<MathScreen> createState() => _MathScreenState();
}
class _MathScreenState extends State<MathScreen> {
bool t1 = true;
bool t2 = true;
bool t3 = true;
TextEditingController t1Controller = TextEditingController();
TextEditingController t2Controller = TextEditingController();
TextEditingController t3Controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: Row(
children: [
Expanded(
child: TextField(
enabled: t1,
keyboardType: TextInputType.number,
controller: t1Controller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
filled: true,
hintStyle: TextStyle(
color: Colors.grey[800],
),
hintText: "",
label: Text("Amount"),
fillColor: Colors.white70,
),
onChanged: (value) {
if ((t3Controller.text == "" || !t3) &&
(t2Controller.text != "")) {
setState(() {
t3 = false;
t1 = true;
t2 = true;
t3Controller.text = value == ""
? ""
: (num.parse(value) *
num.parse(t2Controller.text))
.toString();
});
}
if (t3Controller.text != "" &&
(t2Controller.text == "" || !t2)) {
setState(() {
t2 = false;
t1 = true;
t3 = true;
t2Controller.text = value == ""
? ""
: (num.parse(t3Controller.text) /
num.parse(value))
.toString();
});
}
if (t2Controller.text == "" &&
t1Controller.text == "" &&
t3Controller.text == "") {
setState(() {
t2 = true;
t1 = true;
t3 = true;
});
}
},
),
),
Text(" X "),
Expanded(
child: TextField(
enabled: t2,
keyboardType: TextInputType.number,
controller: t2Controller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
filled: true,
hintStyle: TextStyle(
color: Colors.grey[800],
),
hintText: "",
label: Text("Unit Price"),
fillColor: Colors.white70,
),
onChanged: (value) {
if ((t1Controller.text == "" || !t1) &&
(t3Controller.text != "")) {
setState(() {
t1 = false;
t2 = true;
t3 = true;
t1Controller.text = value == ""
? ""
: (num.parse(t3Controller.text) /
num.parse(value))
.toString();
});
}
if (t1Controller.text != "" &&
(t3Controller.text == "" || !t3)) {
setState(() {
t3 = false;
t1 = true;
t2 = true;
t3Controller.text = value == ""
? ""
: (num.parse(value) *
num.parse(t1Controller.text))
.toString();
});
}
if (t2Controller.text == "" &&
t1Controller.text == "" &&
t3Controller.text == "") {
setState(() {
t2 = true;
t1 = true;
t3 = true;
});
}
},
),
),
Text(" = "),
Expanded(
child: TextField(
enabled: t3,
keyboardType: TextInputType.number,
controller: t3Controller,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30.0),
),
filled: true,
hintStyle: TextStyle(
color: Colors.grey[800],
),
hintText: "",
label: Text("Total Price"),
fillColor: Colors.white70,
),
onChanged: (value) {
if ((t1Controller.text == "" || !t1) &&
(t2Controller.text != "")) {
setState(() {
t1 = false;
t3 = true;
t2 = true;
t1Controller.text = value == ""
? ""
: (num.parse(value) /
num.parse(t2Controller.text))
.toString();
});
}
if (t1Controller.text != "" &&
(t2Controller.text == "" || !t2)) {
setState(() {
t2 = false;
t1 = true;
t3 = true;
t2Controller.text = value == ""
? ""
: (num.parse(value) /
num.parse(t1Controller.text))
.toString();
});
}
if (t2Controller.text == "" &&
t1Controller.text == "" &&
t3Controller.text == "") {
setState(() {
t2 = true;
t1 = true;
t3 = true;
});
}
},
),
),
],
),
),
ElevatedButton(
onPressed: () {
setState(() {
t2 = true;
t1 = true;
t3 = true;
t2Controller.text == "";
t1Controller.text == "";
t3Controller.text == "";
});
},
child: Text("Reset"))
],
),
),
),
);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论