K.k
K.k

Reputation: 489

Flutter: How to delete item from listview?

  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);
                        });
                    },
                  ),
                );
              },
            );
          }
        }
      },
    );
  }

This is my code. My lists come from sqlflite. And I want to delete my item from Listview. But this code doesn't work. I don't know where I made the mistake.

Upvotes: 0

Views: 409

Answers (1)

hysunny
hysunny

Reputation: 111

This behavior is normal. If you print some logs in the build statement, you will find that every time you click the delete button (setState), Widget will build again.

In addition, lists are re-assigned to DB data after each build

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

So, it looks like the delete operation is not working.

This phenomenon if you've seen Flutter setState part of the source code will be well understood.

In setState, the callback is performed first, and then mark dirty

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

So, there are two ways to solve this problem:

(1) Do not directly change the value of lists, but when the delete button is pressed, to delete the data in the database, so that when Widget build again, the data taken out of the database is correct.

(2) Add a flag to judge whether the data is initialized, and then add a judgment before assigning lists. If the data is initialized, assignment operation will not be carried out

I hope it worked for you. ^-^

Upvotes: 1

Related Questions