如何解决如何在Flutter中编辑数组中的元素
我一直在开发一个待办事项列表应用程序,现在我正在尝试实现一个编辑功能,用户可以在其中选择用户想要编辑的元素,最后保存所做的更改。为此,我创建了一个函数,该函数调用存储上载项的数组,然后以该数组中的选定元素为目标,并最终为其提供一个新值,该值将是编辑后的文本。我之前在本机反应中已经使用了此过程,但是由于flutter使用了dart,我遇到了一些问题,例如我不能只添加indexOf(index),因为不能在ToDoElement中使用整数(它是字符串),我也不会这样做。我不知道该如何为所选元素分配新值,因为这是我第二周学习动荡。如何实现此编辑功能?如果我的想法是错误的,请纠正我。
编辑:我已经获得帮助,现在在调用_editToDoItem函数时,由于索引Undefined name 'index'
,在_editDialog上出现错误。
与编辑功能相关的代码
class ToDoElement {
String task;
final DateTime timeOfCreation;
ToDoElement(this.task,this.timeOfCreation);
}
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget {
@override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
void _addToDoItem(String task) {
if(task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task,DateTime.now()));
});
}
}
void _editToDoItem(String newText,int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
void _removeTodoItem(int index) {
setState(() => _toDoItems.removeAt(index));
}
_editDialog(BuildContext context) {
return showDialog(context: context,builder: (context) {
return Dialog(
backgroundColor: Colors.transparent,child: Container(
decoration: BoxDecoration(
color: Colors.white,borderRadius: BorderRadius.all(Radius.circular(20.0)),),padding: EdgeInsets.all(20),height: 180,width: 100,child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: [
Container(
height: 60,child: TextField(
controller: _controller,autofocus: true,style: TextStyle(fontSize: 18,)
),Container(
height: 65,width: double.infinity,margin: EdgeInsets.only(top: 5,child: RaisedButton(
textColor: Colors.white,color: Colors.red,child: Text('EDIT',style: TextStyle(fontSize: 18)),shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),onPressed: () {
_editToDoItem(_controller.text,index); // error on index,Undefined name 'index'
FocusScope.of(context).requestFocus(FocusNode());
},],);
});
}
完整的main.dart
class ToDoElement {
String task;
final DateTime timeOfCreation;
ToDoElement(this.task,/*onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},*/
style: TextStyle(fontSize: 18,decoration: InputDecoration(
hintText: 'Add a task here...',enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),borderSide: BorderSide(color: Colors.red,width: 2),focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),index);
FocusScope.of(context).requestFocus(FocusNode());
},);
});
}
Widget _buildToDoItem(String toDoText,int index) {
return SizedBox(
child: Container(
height: 58,margin: EdgeInsets.only(left: 22.0,right: 22.0,bottom: 12,decoration: BoxDecoration(
border: Border.all(width: 1.5,color: Colors.red),borderRadius: BorderRadius.all(Radius.circular(18)),child: Row(
crossAxisAlignment: CrossAxisAlignment.center,children:[
Expanded(
child: ListTile(
title: Text(
toDoText,style: TextStyle(fontSize: 18),onTap: () => null,FlatButton(
child: Text('Edit',style: TextStyle(color: Colors.red,fontSize: 16.5),onPressed: () => _editDialog(context),FlatButton(
child: Text('Delete',onPressed: () => _removeTodoItem(index),);
}
int compareElement(ToDoElement a,ToDoElement b) =>
a.timeOfCreation.isAfter(b.timeOfCreation) ? -1 : 1;
Widget _buildToDoList() {
_toDoItems.sort(compareElement);
return Expanded(
child: ListView.builder(
itemCount: _toDoItems.length,itemBuilder: (context,index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[index].task,index);
}
},);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),child: AppBar(
centerTitle: true,backgroundColor: Colors.red,title: Text('To Do List',style: TextStyle(fontSize: 24,fontWeight: FontWeight.bold,)
),backgroundColor: Colors.white,body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},child: Column(
crossAxisAlignment: CrossAxisAlignment.center,children: [
Container(
height: 60,margin: EdgeInsets.all(22),child: Row(
crossAxisAlignment: CrossAxisAlignment.center,children: [
Expanded(
flex: 10,child: Container(
height: double.infinity,child: TextField(
controller: _controller,onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},decoration: InputDecoration(
hintText: 'Add a task here...',enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),Expanded(
flex: 4,margin: EdgeInsets.only(left: 12),child: RaisedButton(
textColor: Colors.white,child: Text('ADD',shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),onPressed: () {
_addToDoItem(_controller.text);
_controller.clear();
FocusScope.of(context).requestFocus(FocusNode());
},_buildToDoList()
]
),);
}
}
如有任何疑问,请在评论中让我知道;)
解决方法
出现错误的原因是因为您使用.indexOf
是错误的。应该使用它来发现已知元素的索引,而您已经知道该索引,而想更改该元素。相反,您可以使用[]
运算符:someList[index] = someNewValue
直接访问元素。
但是,在此之前您也有一个错误。在这种情况下,final items = [..._toDoItems];
行是不必要的,并且在其他情况下会导致严重的问题(例如,如果您的数据列表是int
或String
的列表,因为它们是常量)。此行所做的只是将_toDoItems
中的所有元素复制(解压缩)到新列表中。相反,您可以直接编辑原始列表。
最后,您的ToDoElement
属性task
是final
,但是您想修改task
。但是,您不能更改最终变量。您可以选择将_toDoItems
中的元素替换为新的ToDoElement
(从头开始),也可以将其更改为非最终变量。我建议后者。
无论如何,要解决此问题(使用后一种方法),只需将_editToDoItem
方法更改为以下内容即可:
void _editToDoItem(int index,String newText) {
_toDoItems[index].task = newText;
setState(() {});
}
然后从final
中删除ToDoElement
:
class ToDoElement {
String task;
final DateTime timeOfCreation;
ToDoElement(this.task,this.timeOfCreation);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。