首页 > 解决方案 > Flutter:如何从列表视图中删除项目?

问题描述

  DBHelper dbHelper = DBHelper();

  List<Map<String, dynamic>> lists;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Map<String, dynamic>>>(
      future: dbHelper.selectMemo(userkey, 1),
      builder: (context, snapshot){
        if(snapshot.hasData){
          if(snapshot.data.length != 0){
            lists = List<Map<String, dynamic>>.from(snapshot.data);

            return ListView.separated(
              separatorBuilder: (context, index){
                return Divider(
                  thickness: 0,
                );
              },
              itemCount: lists.length,
              itemBuilder: (context, index){
                return ListTile(
                  title: Text(lists[index]["memo"]),
                  trailing: IconButton(
                      icon: Icon(Icons.delete),
                    onPressed: (){
                        setState(() {
                          lists = List.from(lists)..removeAt(index);
                        });
                    },
                  ),
                );
              },
            );
          }
        }
      },
    );
  }

这是我的代码。我的列表来自 sqlflite。我想从 Listview 中删除我的项目。但是这段代码不起作用。我不知道我在哪里犯了错误。

标签: flutter

解决方案


这种行为是正常的。如果在构建语句中打印一些日志,会发现每次点击删除按钮(setState),Widget都会再次构建。

此外,每次构建后都会将列表重新分配给数据库数据

lists = List<Map<String, dynamic>>.from(snapshot.data);

因此,看起来删除操作不起作用。

这种现象如果你看过 Flutter的setState部分源码就会很好理解。

在 setState 中,首先执行回调,然后标记为脏

void setState(VoidCallback fn) {
  final dynamic result = fn() as dynamic;
  _element.markNeedsBuild();
}

所以,有两种方法可以解决这个问题:

(1)不要直接改变lists的值,而是在按下delete按钮时,删除数据库中的数据,这样再次构建Widget时,从数据库中取出的数据是正确的。

(2)添加一个标志来判断数据是否被初始化,然后在分配列表之前添加一个判断。如果数据被初始化,则不会进行赋值操作

我希望它对你有用。^-^


推荐阅读