Flutter ListView delete and undo operation

前端 未结 2 1781
挽巷
挽巷 2021-01-13 21:36

How can I implement a ListView that has a Dismissible widget, and when I swipe, I can delete the item, but how can I bring it back when tapping say

相关标签:
2条回答
  • 2021-01-13 21:57

    If you are retrieving data from a remote server such as firestore, follow this example below:

    StreamBuilder<QuerySnapshot>(
                stream: db.collection("collection name").snapshots(),
                // ignore: missing_return
                builder:
                    (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
                  if (snapshot.hasError) {
                    return Center(child: Text('Sorry something went wrong'));
                  }
    
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Center(child: CircularProgressIndicator());
                  }
                  return ListView.builder(
                      itemCount: snapshot.data.docs.length,
                      shrinkWrap: true,
                      physics: NeverScrollableScrollPhysics(),
                      itemBuilder: (context, index){
                        DocumentSnapshot document = snapshot.data.docs[index];
                        final documentID = snapshot.data.docs[index].id;
                        final list = snapshot.data.docs;
                        return Dismissible(
                          confirmDismiss: (direction) => promptUser(direction), //U can use showDialog to build this method for confirmation if need be.
    
                          // Each Dismissible must contain a Key. Keys allow
                          // Flutter to uniquely identify widgets.
                          key: Key(documentID),
                          onDismissed: (direction){
                            removeFromDb(documentID);
                            setState(() {
                              // Remove the item from the data source.
                              list.removeAt(index);
    
                              String action;
                              if (direction == DismissDirection.endToStart) {
                                removeFromDb(documentID);
                                action = "deleted";
                              }
    
                              _key.currentState
                                ..removeCurrentSnackBar()
                                ..showSnackBar(
                                  SnackBar(
                                    content: Text("Data $documentID $action"),
                                    action: SnackBarAction(
                                        label: "UNDO",
                                        onPressed: () => setState(() => list.insert(index, deletedItem),)
                                    ),
                                  ),
                                );
                            });
                          },
                          // Show a red background as the item is swiped away
                          background: Container(
                            color: Colors.amber,
                            padding: EdgeInsets.symmetric(horizontal: 20),
                            alignment: AlignmentDirectional.centerEnd,
                            child: Icon(
                              Icons.delete,
                              color: Colors.white,
                            ),
                          ),
                          child: GestureDetector(
                            onTap: () => _onSelected(index),
                            child: Container(
                              //==> change bg color when index is selected ==>
                              color: _selectedIndex != null && _selectedIndex == index
                                  ? Colors.grey[100]
                                  : Colors.white,
                              padding: EdgeInsets.only(top: 15, left: 10, right: 10),
                                    height: 180,
                                    width: double.maxFinite,
                              child: Card(
                                elevation: 5,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(5),
                                ),
                                child: Row(
                                  mainAxisAlignment: MainAxisAlignment.start,
                                  crossAxisAlignment: CrossAxisAlignment.center,
                                  children: [
                                    Padding(
                                      padding: EdgeInsets.all(5.0),),
                                    Padding(
                                      padding: EdgeInsets.only(top: 30, left: 1),
                                      child: Column(
                                        children: [
                                          Text(
                                            document.data()['same name in document/field'],
                                            style: TextStyle(
                                              decorationStyle: TextDecorationStyle.double,
                                              color: Colors.black,
                                              fontSize: 20,
                                              fontWeight: FontWeight.w700,
                                            ),
                                          ),
                                          SizedBox(
                                            height: 9,
                                          ),
                                          Text(document.data()['same name in document/field'],
                                            style: TextStyle(
                                              decorationStyle: TextDecorationStyle.double,
                                              color: Colors.black87,
                                              fontSize: 16,
                                            ),),
                                          SizedBox(
                                            height: 9,
                                          ),
                                          Text(document.data()['same name in document/field'],
                                            style: TextStyle(
                                              decorationStyle: TextDecorationStyle.double,
                                              color: Colors.black87,
                                            ),
                                          ),
                                          SizedBox(
                                            height: 6,
                                          ),
                                          Text(document.data()['same name in document/field'],
                                            style: TextStyle(
                                              decorationStyle: TextDecorationStyle.double,
                                              color: Colors.black87,
                                            ),
                                          ),
                                        ],
                                      ),
                                    ),
                                    SizedBox(
                                      width: 15,
                                    ),
                                    Container(
                                      width: 1,
                                      height: 130,
                                      color: Colors.black54,
                                    ),
                                    SizedBox(
                                      width: 8,
                                    ),
                                    Padding(
                                      padding: EdgeInsets.only(top: 20, bottom: 20),
                                      child: Container(
                                          height: 120,
                                          width: 145,
                                          child: SingleChildScrollView(
                                              child: Align(
                                                alignment: Alignment.center,
                                                child: Text(
                                                  document.data()['same name in document/field'],
                                                  style: TextStyle(
                                                      color: Colors.black
                                                  ),
                                                ),
                                              ))),
                                    ),
                                  ],
                                ),
                              ),
                            ),
                          ),
                        );
                      }
                  );
                  
                })
    

    Couldn't show screenshot but this will work alright especially if you understand Firestore

    0 讨论(0)
  • 2021-01-13 22:17

    All you needed is

    _list.insert(index, yourDeletedItem);
    

    Here is the complete code with SnackBar added.

    GlobalKey<ScaffoldState> _key = GlobalKey(); // added
    List<String> _list = List.generate(10, (index) => "${index}");
    
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        key: _key, // added
        appBar: AppBar(title: Text("App")),
        body: ListView.builder(
          itemCount: _list.length,
          itemBuilder: (context, index) {
            return Dismissible(
              key: Key(_list[index]),
              child: ListTile(title: Text(_list[index])),
              background: Container(color: Colors.red),
              onDismissed: (direction) {
                setState(() {
                  // added this block 
                  String deletedItem = _list.removeAt(index);
                  _key.currentState
                   ..removeCurrentSnackBar()
                   ..showSnackBar(
                    SnackBar(
                      content: Text("Deleted \"${deletedItem}\""),
                      action: SnackBarAction(
                        label: "UNDO",
                        onPressed: () => setState(() => _list.insert(index, deletedItem),) // this is what you needed
                      ),
                    ),
                  );
                });
              },
            );
          },
        ),
      );
    }
    

    Screenshot

    0 讨论(0)
提交回复
热议问题