使用 Dart 和 Flutter,如何将动态小部件中的数据保存到另一个列表内的地图列表中
Using Dart and Flutter, how can I save data from a dynamic widget, into a list of maps, that is inside of another list
如果有人问过这个问题,我们深表歉意。
下面是我正在构建的应用程序的简化版本的代码。
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TextEditingController dutyDescriptionController = TextEditingController();
//this list holds a list of DynamicWidgets()
List<DynamicWidget> dynamicList = [];
//this list holds a list of duties
List<Map<String, dynamic>> dutiesList = [];
//this list holds a list of activities within a duty, currently just dummy data
List<Map<String, dynamic>> activitiesList = [
{'description': 'Some Activity 1'},
{'description': 'Some Activity 2'},
];
//add DynamicWidget to the dynamicList (max of 3 widgets)
addDynamic() {
if (dynamicList.length <= 2) {
dynamicList.add(DynamicWidget());
setState(() {});
}
}
//submit the data
submitData() {
//there should only be 1 element in the duties list hence why I clear the list prior to adding to it
//not sure if this is the correct way to go about it
dutiesList.clear();
dutiesList.add({
'dutyDescription': dutyDescriptionController.text,
'activityDescription': activitiesList,
});
print(dutiesList);
//completely stuck here.
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dynamic Widget'),
),
body: ListView(
children: [
TextField(
controller: dutyDescriptionController,
decoration: InputDecoration(labelText: 'Duty Description'),
),
Expanded(
flex: 1,
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: dynamicList.length,
itemBuilder: (BuildContext context, int index) => dynamicList[index],
),
),
ElevatedButton(
onPressed: addDynamic,
child: Text('Add Activity'),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
submitData();
},
child: Icon(Icons.save),
),
);
}
}
//this widget is created dynamically and displayed in a listview.builder inside MyApp()
class DynamicWidget extends StatelessWidget {
final TextEditingController controller1 = TextEditingController();
@override
Widget build(BuildContext context) {
return TextField(
controller: controller1,
decoration: InputDecoration(labelText: 'Activity Description'),
);
}
}
该应用程序有一个文本字段,用于存储工作轮班的职责。
在其下方是一个标记为 'Add Activity' 的按钮。按下时,它会将 DynamicWidget() 添加到 dynamicList 中,与 listview.builder 一起使用以显示小部件。
还有一个浮动操作按钮,当按下该按钮时,当前会将 'Duty Description' 文本字段的内容添加到 dutiesList 列表以及 activitiesList 的内容(当前使用虚拟数据进行硬编码)。
目前dutiesList中的数据是这样的。如果不是很明显,键 'activityDescription' 就是我存储活动列表的地方。
[
{
dutyDescription: SomeDuty,
activityDescription: [
{
description: SomeActivity1
},
{
description: SomeActivity2
}
]
}
]
我想要做的是从一个空的 activitiesList 开始并添加 'Activity Description' 文本字段的内容(因为在生产应用程序中将有多个文本字段以及位于 DynamicWidget 内部的其他用户输入源) 到 activitiesList 但我不知道该怎么做。
我对 Flutter 还很陌生,学习速度很快,但我已经盯着它看了很长时间了。任何帮助都会很棒。
提前致谢。
你真的试过运行这段代码吗?我无法想象在另一个 ListView 中的 Expanded 中的 ListView 不会导致错误。
如果“应该只有 1 个元素”,为什么要将“职责”列为一个列表?
您要求的解决方案:
为了整洁起见,把下面的函数放在_MyAppState
里面,紧挨着addDynamic
和submitData
void update(String description) {
setState(() {
activitiesList.add({'description': description});
});
}
然后将 DynamicWidget
更改为
class DynamicWidget extends StatefulWidget {
final Function update;
DynamicWidget({required this.update});
@override
_DynamicWidgetState createState() => _DynamicWidgetState();
}
class _DynamicWidgetState extends State<DynamicWidget> {
String description = '';
@override
Widget build(BuildContext context) {
return SizedBox(
height: 80.0,
width: 350.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 300.0,
child: TextField(
onChanged: (String text) {
setState(() {
description = text;
});
},
decoration: InputDecoration(labelText: 'Activity Description'),
),
),
IconButton(
icon: const Icon(Icons.arrow_forward),
tooltip: 'Submit',
onPressed: () => widget.update(description),
),
],
),
);
}
}
像这样调用DynamicWidget
DynamicWidget(update: update)
如果您在提交前后打印 activitiesList
,您将看到您输入的任何内容都已添加。
如果有人问过这个问题,我们深表歉意。
下面是我正在构建的应用程序的简化版本的代码。
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
TextEditingController dutyDescriptionController = TextEditingController();
//this list holds a list of DynamicWidgets()
List<DynamicWidget> dynamicList = [];
//this list holds a list of duties
List<Map<String, dynamic>> dutiesList = [];
//this list holds a list of activities within a duty, currently just dummy data
List<Map<String, dynamic>> activitiesList = [
{'description': 'Some Activity 1'},
{'description': 'Some Activity 2'},
];
//add DynamicWidget to the dynamicList (max of 3 widgets)
addDynamic() {
if (dynamicList.length <= 2) {
dynamicList.add(DynamicWidget());
setState(() {});
}
}
//submit the data
submitData() {
//there should only be 1 element in the duties list hence why I clear the list prior to adding to it
//not sure if this is the correct way to go about it
dutiesList.clear();
dutiesList.add({
'dutyDescription': dutyDescriptionController.text,
'activityDescription': activitiesList,
});
print(dutiesList);
//completely stuck here.
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dynamic Widget'),
),
body: ListView(
children: [
TextField(
controller: dutyDescriptionController,
decoration: InputDecoration(labelText: 'Duty Description'),
),
Expanded(
flex: 1,
child: ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: dynamicList.length,
itemBuilder: (BuildContext context, int index) => dynamicList[index],
),
),
ElevatedButton(
onPressed: addDynamic,
child: Text('Add Activity'),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
submitData();
},
child: Icon(Icons.save),
),
);
}
}
//this widget is created dynamically and displayed in a listview.builder inside MyApp()
class DynamicWidget extends StatelessWidget {
final TextEditingController controller1 = TextEditingController();
@override
Widget build(BuildContext context) {
return TextField(
controller: controller1,
decoration: InputDecoration(labelText: 'Activity Description'),
);
}
}
该应用程序有一个文本字段,用于存储工作轮班的职责。
在其下方是一个标记为 'Add Activity' 的按钮。按下时,它会将 DynamicWidget() 添加到 dynamicList 中,与 listview.builder 一起使用以显示小部件。
还有一个浮动操作按钮,当按下该按钮时,当前会将 'Duty Description' 文本字段的内容添加到 dutiesList 列表以及 activitiesList 的内容(当前使用虚拟数据进行硬编码)。
目前dutiesList中的数据是这样的。如果不是很明显,键 'activityDescription' 就是我存储活动列表的地方。
[
{
dutyDescription: SomeDuty,
activityDescription: [
{
description: SomeActivity1
},
{
description: SomeActivity2
}
]
}
]
我想要做的是从一个空的 activitiesList 开始并添加 'Activity Description' 文本字段的内容(因为在生产应用程序中将有多个文本字段以及位于 DynamicWidget 内部的其他用户输入源) 到 activitiesList 但我不知道该怎么做。
我对 Flutter 还很陌生,学习速度很快,但我已经盯着它看了很长时间了。任何帮助都会很棒。
提前致谢。
你真的试过运行这段代码吗?我无法想象在另一个 ListView 中的 Expanded 中的 ListView 不会导致错误。
如果“应该只有 1 个元素”,为什么要将“职责”列为一个列表?
您要求的解决方案:
为了整洁起见,把下面的函数放在_MyAppState
里面,紧挨着addDynamic
和submitData
void update(String description) {
setState(() {
activitiesList.add({'description': description});
});
}
然后将 DynamicWidget
更改为
class DynamicWidget extends StatefulWidget {
final Function update;
DynamicWidget({required this.update});
@override
_DynamicWidgetState createState() => _DynamicWidgetState();
}
class _DynamicWidgetState extends State<DynamicWidget> {
String description = '';
@override
Widget build(BuildContext context) {
return SizedBox(
height: 80.0,
width: 350.0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 300.0,
child: TextField(
onChanged: (String text) {
setState(() {
description = text;
});
},
decoration: InputDecoration(labelText: 'Activity Description'),
),
),
IconButton(
icon: const Icon(Icons.arrow_forward),
tooltip: 'Submit',
onPressed: () => widget.update(description),
),
],
),
);
}
}
像这样调用DynamicWidget
DynamicWidget(update: update)
如果您在提交前后打印 activitiesList
,您将看到您输入的任何内容都已添加。