Search code examples
flutterdartflutter-widgetdismissible

Flutter Dismissible Widget re shows the widget after dismissing


i am trying to make a list in which its tiles can be deleted when dragged so i used the Dismissible widget and everything is working as i wanted, however when dragging the tile to dismiss it the tile re shows for a few moment and disappear, a demo of what i mean is shown in this video

FutureBuilder(
        future: getMyFavData(),
        builder: (context, snapshot) {
          if (snapshot.data == null)
            return Container(
                child: Center(
                    child: CircularProgressIndicator(
              backgroundColor: Colors.red,
            )));
          else
            return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, index) {
                  var monthOfProductList =
                      snapshot.data.elementAt(index)['date'].toDate().month;
                  var monthNow = DateTime.now().month;
                  bool newItem = false;
                  if (monthNow - monthOfProductList == 0) {
                    newItem = true;
                  }
                  return Dismissible(
                    key: UniqueKey(),
                    onDismissed: (direction) async  {
                      if (direction == DismissDirection.startToEnd) {

                        await deleteFromDataBase(
                            snapshot.data.elementAt(index).documentID);

                        setState(() {
                          snapshot.data.remove(index);
                        });

                      }
                    },
                    background: Container(
                      color: Colors.red,
                      child: Row(
                        children: [
                          Icon(
                            Icons.delete_forever,
                            color: Colors.white,
                            size: 100,
                          ),
                        ],
                      ),
                    ),
                    direction: DismissDirection.startToEnd,
                    child: GestureDetector(
                      onTap: () {

                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => ProductFullScreenView(
                                      productInfo: snapshot.data.elementAt(index),
                                    )));
                      },
                      child: ProductListCardVerticalFavorite(),
                    ),
                  );
                });
        });

i am not sure where the problem is, any help would be appreciated


Solution

  • You used FutureBuilder to fetch a list of data and on the onDismissed you remove it.

    When you dismiss an item, the widget that holds it will rebuild again so you don't need to call the setState.

    Also when you call a remove function(deleteFromDataBase), that's going to remove some real saved data so you don't need to remove it from data you fetched because here when an item is removed a function will be called to delete it from real saved data too and the widget will be rebuilt and another call(getMyFavData()) would occur on saved data to fetch them but this time the result is all of the previous one without the removed item.

    I made a simple example out of your code and made a fake future call:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(Home());
    }
    
    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      List<String> lst = [
        '1',
        '2',
        '4',
        '5',
        '6',
        '7',
        '8',
        '9',
        '10',
        '11',
      ];
      Future<List<String>> getMyFavData() async {
        return Future.value(lst);
      }
    
      Future<void> deleteFromDataBase(int index) async {
        Future.delayed(Duration(milliseconds: 500)).then((_) {
          lst.removeAt(index);
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: FutureBuilder(
                future: getMyFavData(),
                builder: (context, snapshot) {
                  if (snapshot.data == null)
                    return Container(
                      child: Center(
                        child:
                            CircularProgressIndicator(backgroundColor: Colors.red),
                      ),
                    );
                  else
                    return ListView.builder(
                        itemCount: snapshot.data.length,
                        itemBuilder: (context, index) {
                          return Dismissible(
                              key: UniqueKey(),
                              onDismissed: (direction) async {
                                if (direction == DismissDirection.startToEnd) {
                                  await deleteFromDataBase(index);
                                }
                              },
                              background: Container(
                                color: Colors.red,
                                alignment: Alignment.centerLeft,
                                child: Icon(
                                  Icons.delete_forever,
                                  color: Colors.white,
                                ),
                              ),
                              direction: DismissDirection.startToEnd,
                              child: Container(
                                width: MediaQuery.of(context).size.width,
                                child: Text(lst[index]),
                                color: Colors.blue,
                                margin: EdgeInsets.all(5.0),
                              ));
                        });
                }),
          ),
        );
      }
    }