Flutter ListView的删除和撤消操作

时间:2019-01-22 07:13:10

标签: dart flutter

如何实现具有ListView小部件的Dismissible,并且在滑动时可以删除该项目,但是在轻按SnackBar时如何将其恢复的动作。谁能给我榜样吗?这是我在State课堂上的经历。

List<String> _list = List.generate(10, (index) => "${index}");

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(title: Text("App")),
    body: ListView.builder(
      itemCount: _list.length,
      itemBuilder: (context, index) {
        return Dismissible(
          key: Key(_list[index]),
          background: Container(color: Colors.red,),
          child: ListTile(title: Text(_list[index])),
          onDismissed: (direction) => setState(() => _list.removeAt(index))
        );
      },
    )
  );
} 

2 个答案:

答案 0 :(得分:5)

您需要的只是

_list.insert(index, yourDeletedItem);

以下是添加了SnackBar的完整代码。

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

屏幕截图

enter image description here

答案 1 :(得分:0)

如果要从远程服务器(如Firestore)中检索数据,请按照以下示例操作:

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

无法显示屏幕截图,但这可以正常运行,尤其是如果您了解Firestore