flutter - 如何在Flutter中编辑列表中的选定项目

标签 flutter dart flutter-layout

我一直在尝试向我的待办事项列表中添加一个编辑功能,用户可以在其中选择要编辑的项目,然后应该弹出一个对话框,其中有一个文本字段可输入所选项目的新值,保存更改的按钮。当前,我有一个函数,该函数调用存储任务的数组,然后应该使用索引触发所选项目,以便最后在onPressed时可以给所选值一个新值,请将此编辑功能视为instagrams,除了它编辑文本。
问题是在对话框的编辑按钮中调用该函数时出现的,因为我像onPressed: () => _editToDoItem(_controller.text, index)那样执行此操作,并且由于必须在其中传递2个参数,所以我遇到的错误是Undefined name 'index'。如何解决此问题以使此编辑功能起作用?顺便说一句,由于这个错误,我没有尝试编辑功能,所以如果功能或代码的任何部分不正确,请更正我。
一切与下面的编辑功能有关。

  List<ToDoElement> _toDoItems = [];
  TextEditingController _controller = TextEditingController();

  // this function adds a task to the list
  void _addToDoItem(String task) {
    if(task.isNotEmpty) {
      setState(() {  
        _toDoItems.add(ToDoElement(task, DateTime.now()));
      });
    }
  }

  // this is the function that is supposed to edit the selected index from the _toDoItems array
  void _editToDoItem(String newText, int index) {
    setState(() {
      _toDoItems[index].task = newText;
    });
  }

  _editDialog(BuildContext context) {
    return showDialog(context: context, builder: (context) {
      return Dialog(
        child: Container(
          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'),
                    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, 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,
                    /*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)),
                        borderSide: BorderSide(color: Colors.red, width: 2),
                      ),
                      
                    ),
                  )
                ),

              
                   
                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);
                      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', style: TextStyle(color: Colors.red, fontSize: 16.5),),
              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,
                          autofocus: true,
                          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)),
                              borderSide: BorderSide(color: Colors.red, width: 2),
                            ),
                            
                          ),
                        ),
                      ),
                      
                    ),
                    Expanded(
                      flex: 4,    
                      child: Container(
                        height: double.infinity,
                        margin: EdgeInsets.only(left: 12),
                        child: RaisedButton(
                          textColor: Colors.white,
                          color: Colors.red,
                          child: Text('ADD', style: TextStyle(fontSize: 18)),
                          
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.all(Radius.circular(12)),
                          ),
                          onPressed: () {
                            _addToDoItem(_controller.text);
                            _controller.clear();
                            FocusScope.of(context).requestFocus(FocusNode());
                          },
                        ),
                      ),                                          
                    ),
                  ],
                ),
              ), 
              _buildToDoList()
            ]
          ), 
                 
        ),
    );
  }
}

如果您有任何疑问,请在评论中让我知道;)

最佳答案

您可以在下面复制粘贴运行完整代码
您可以将index提供给_editDialog,然后_editToDoItem可以获取index程式码片段

_editDialog(BuildContext context, int index)
...
FlatButton(
      child: Text(
        'Edit',
        style: TextStyle(color: Colors.red, fontSize: 16.5),
      ),
      onPressed: () => _editDialog(context, index),
    ),
工作演示
enter image description here
完整的代码
import 'package:flutter/material.dart';

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();
  TextEditingController _controller1 = 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, int index) {
    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,
                        /*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)),
                            borderSide: BorderSide(color: Colors.red, width: 2),
                          ),
                        ),
                      )),
                  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);
                        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, index),
            ),
            FlatButton(
              child: Text(
                'Delete',
                style: TextStyle(color: Colors.red, fontSize: 16.5),
              ),
              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: _controller1,
                      autofocus: true,
                      onSubmitted: (val) {
                        _addToDoItem(val);
                        _controller1.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)),
                          borderSide: BorderSide(color: Colors.red, width: 2),
                        ),
                      ),
                    ),
                  ),
                ),
                Expanded(
                  flex: 4,
                  child: Container(
                    height: double.infinity,
                    margin: EdgeInsets.only(left: 12),
                    child: RaisedButton(
                      textColor: Colors.white,
                      color: Colors.red,
                      child: Text('ADD', style: TextStyle(fontSize: 18)),
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.all(Radius.circular(12)),
                      ),
                      onPressed: () {
                        _addToDoItem(_controller1.text);
                        _controller1.clear();
                        FocusScope.of(context).requestFocus(FocusNode());
                      },
                    ),
                  ),
                ),
              ],
            ),
          ),
          _buildToDoList()
        ]),
      ),
    );
  }
}

关于flutter - 如何在Flutter中编辑列表中的选定项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63404236/

相关文章:

flutter - WidgetsBindingObserver 是否适用于无状态小部件?

flutter - 滑动面板内的嵌套ScrollView小部件

sqlite - 用flutter中的sqlite数据库中的数据填充下拉菜单

flutter - 如何在Flutter中制作下雨动画

android - "Execution failed for task ' :app:packageDebug ' > Failed to generate v1 signature" exception while compiling Flutter

android - Flutter Location Package帮助:我想将用户证明的坐标提取为单独的var/string或double

java - 带有自签名证书的 Flutter https

flutter - Flutter中自定义textScaleFactor的通用范围是多少?

Flutter - 如何制作自定义 TabBar

flutter - 如何在布局中随机放置小部件