英文:
TextEditingController value not getting saved to a list
问题
I have a List<Map<String,dynamic>>
called woodsArray
.
我有一个名为woodsArray
的List<Map<String,dynamic>>
。
I require to add three parameters named length, breadth, and area inside this list. For this, I am using a ListView.builder
and three lists of TextEditingController
. MY requirement is such that the area should be based on length and breadth. Though it is rendering correctly, but it is not getting added to woodsArray
.
我需要在这个列表中添加名为length、breadth和area的三个参数。为此,我使用了ListView.builder
和三个TextEditingController
列表。我的要求是面积应该基于长度和宽度。虽然它呈现得很正确,但它没有添加到woodsArray
中。
This is what I have done so far.
这是我迄今为止所做的。
List<Map<String, dynamic>> woodsArray = [];
List<TextEditingController> woodlengthControllers = [];
List<TextEditingController> woodbreadthControllers = [];
List<TextEditingController> woodAreaControllers = [];
在ListView.builder
中,
在ListView.builder
中,
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: woodsArray.length,
itemBuilder: (BuildContext context, int index) {
woodlengthControllers.add(
TextEditingController(text: ''''),
);
woodbreadthControllers.add(TextEditingController(text: ''''));
woodAreaControllers.add(TextEditingController(text: ''''));
///// AREA CALCULATION /////
if (woodlengthControllers[index].text != ''' &&
woodbreadthControllers[index].text != '''') {
Future.delayed(Duration.zero, () {
setState(() {
woodAreaControllers[index].text =
((num.tryParse(woodlengthControllers[index].text))! *
(num.tryParse(
woodbreadthControllers[index].text))! *
0.00001111)
.toStringAsFixed(2);
});
});
}
//////////////////////////
return Row(
children:[
SizedBox(
width: 110,
child: TextFormField(
controller: woodlengthControllers[index],
style: formPrimaryTextStyle(context),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelStyle: formPrimaryTextStyle(context),
),
onChanged: (val) {
woodsArray[index]['wood_length'] =
woodlengthControllers[index].text;
},
),
),
SizedBox(
width: 110,
child: TextFormField(
controller: woodbreadthControllers[index],
style: formPrimaryTextStyle(context),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelStyle: formPrimaryTextStyle(context),
),
onChanged: (val) {
woodsArray[index]['wood_breadth'] =
woodbreadthControllers[index].text;
},
),
),
SizedBox(
width: 110,
child: TextFormField(
controller: woodAreaControllers[index],
style: formPrimaryTextStyle(context),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelStyle: formPrimaryTextStyle(context),
),
onChanged: (val) {
woodsArray[index]['wood_area'] =
woodAreaControllers[index].text;
},
),
),
],
);
},
),
在这一点上,面积在ListView
中呈现得很正确。但是当我尝试打印woodsArray
时,它只显示了我定义的长度和宽度,而没有自动根据长度和宽度控制器的值计算的面积。例如,请考虑以下情况。
在这一点上,面积在ListView
中呈现得很正确。但是当我尝试打印woodsArray
时,它只显示了我定义的长度和宽度,而没有自动根据长度和宽度控制器的值计算的面积。例如,请考虑以下情况。
woodsArray=[{'wood_length':1200, 'wood_breadth':300}]
(No 'wood_area')
woodsArray=[{'wood_length':1200, 'wood_breadth':300}]
(没有'wood_area')
What am i doing wrong? Can someone suggest me something I should do differently?
我做错了什么?有人能建议我应该做些什么不同吗?
英文:
I have a List<Map<String,dynamic>>
called woodsArray
.
I require to add three parameters named length, breadth, and area inside this list. For this, I am using a ListView.builder
and three lists of TextEditingController
. MY requirement is such that the area should be based on length and breadth. Though it is rendering correctly, but it is not getting added to woodsArray
.
This is what I have done so far.
List<Map<String, dynamic>> woodsArray = [];
List<TextEditingController> woodlengthControllers = [];
List<TextEditingController> woodbreadthControllers = [];
List<TextEditingController> woodAreaControllers = [];
In the ListView.builder
,
ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: woodsArray.length,
itemBuilder: (BuildContext context, int index) {
woodlengthControllers.add(
TextEditingController(text: ''),
);
woodbreadthControllers.add(TextEditingController(text: ''));
woodAreaControllers.add(TextEditingController(text: ''));
///// AREA CALCULATION /////
if (woodlengthControllers[index].text != '' &&
woodbreadthControllers[index].text != '') {
Future.delayed(Duration.zero, () {
setState(() {
woodAreaControllers[index].text =
((num.tryParse(woodlengthControllers[index].text))! *
(num.tryParse(
woodbreadthControllers[index].text))! *
0.00001111)
.toStringAsFixed(2);
});
});
},
//////////////////////////
return Row(
children:[
SizedBox(
width: 110,
child: TextFormField(
controller: woodlengthControllers[index],
style: formPrimaryTextStyle(context),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelStyle: formPrimaryTextStyle(context),
),
onChanged: (val) {
woodsArray[index]['wood_length'] =
woodlengthControllers[index].text;
},
),
),
SizedBox(
width: 110,
child: TextFormField(
controller: woodbreadthControllers[index],
style: formPrimaryTextStyle(context),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelStyle: formPrimaryTextStyle(context),
),
onChanged: (val) {
woodsArray[index]['wood_breadth'] =
woodbreadthControllers[index].text;
},
),
),
SizedBox(
width: 110,
child: TextFormField(
controller: woodAreaControllers[index],
style: formPrimaryTextStyle(context),
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelStyle: formPrimaryTextStyle(context),
),
onChanged: (val) {
woodsArray[index]['wood_area'] =
woodAreaControllers[index].text;
},
),
),
],
);
},
),
Up to this point, the area gets rendered correctly in the ListView
. But when i try to print the woodsArray
, it only shows the length and the breadth which i defined , not the area which was getting calculated automatically based on the length and breadth controller values. Consider this for example.
woodsArray=[{'wood_length':1200, 'wood_breadth':300}]
(No 'wood_area')
What am i doing wrong? Can someone suggest me something I should do differently?
答案1
得分: 1
我已经重新编写了您的代码,以我认为更好的方式。请尝试以下完整可工作的示例:
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: MainPage()));
}
class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key);
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
List<Wood> woodsArray = [];
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: woodsArray.length,
itemBuilder: (BuildContext context, int index) {
final Wood wood = woodsArray[index];
return Row(
children: [
SizedBox(
width: 110,
child: TextFormField(
controller: wood.lengthController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
onChanged: (val) {
wood.calculateArea();
},
),
),
SizedBox(
width: 110,
child: TextFormField(
controller: wood.breadthController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
onChanged: (val) {
wood.calculateArea();
},
),
),
SizedBox(
width: 110,
child: TextFormField(
enabled: false,
controller: wood.areaController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
),
],
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
print(woodsArray);
woodsArray.add(Wood('1200', '300'));
});
},
child: const Icon(Icons.add),
),
);
}
}
class Wood {
TextEditingController lengthController;
TextEditingController breadthController;
TextEditingController areaController = TextEditingController();
Wood(String length, String breadth)
: lengthController = TextEditingController(text: length),
breadthController = TextEditingController(text: breadth) {
calculateArea();
}
void calculateArea() {
final l = num.tryParse(length);
final b = num.tryParse(breadth);
if (l != null && b != null) {
areaController.text = (l * b * 0.0001111).toStringAsFixed(2);
}
}
String get length => lengthController.text;
String get breadth => breadthController.text;
String get area => areaController.text;
@override
String toString() => 'Wood(length: $length, breadth: $breadth, area: $area)';
}
请注意,我不知道formPrimaryTextStyle
的实现,所以我在代码中没有包含它。按下"+"按钮将添加一个新的Wood项目,并打印当前的Wood列表。希望这能帮助您更好地进行软件开发。
英文:
I've reworked your code in a way that I think is much better. Try out this full working example
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(home: MainPage()));
}
class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key);
@override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
List<Wood> woodsArray = [];
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: woodsArray.length,
itemBuilder: (BuildContext context, int index) {
final Wood wood = woodsArray[index];
return Row(
children: [
SizedBox(
width: 110,
child: TextFormField(
controller: wood.lengthController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
onChanged: (val) {
wood.calculateArea();
},
),
),
SizedBox(
width: 110,
child: TextFormField(
controller: wood.breadthController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
onChanged: (val) {
wood.calculateArea();
},
),
),
SizedBox(
width: 110,
child: TextFormField(
enabled: false,
controller: wood.areaController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
),
],
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(
() {
print(woodsArray);
woodsArray.add(Wood('1200', '300'));
},
),
child: const Icon(Icons.add),
),
);
}
}
class Wood {
TextEditingController lengthController;
TextEditingController breadthController;
TextEditingController areaController = TextEditingController();
Wood(String length, String breadth)
: lengthController = TextEditingController(text: length),
breadthController = TextEditingController(text: breadth) {
calculateArea();
}
void calculateArea() {
final l = num.tryParse(length);
final b = num.tryParse(breadth);
if (l != null && b != null) {
areaController.text = (l * b * 0.0001111).toStringAsFixed(2);
}
}
String get length => lengthController.text;
String get breadth => breadthController.text;
String get area => areaController.text;
@override
String toString() => 'Wood(length: $length, breadth: $breadth, area: $area';
}
Note that I had to leave out the calls to formPrimaryTextStyle
because I didn't know the implementation, so you could add that in again. Pressing the + will add a new Wood item and also print the current list of wood. I hope it gives you insight to better software development.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论