英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论