如何实现滑动以删除列表视图以从 Firestore 中删除数据

Posted

技术标签:

【中文标题】如何实现滑动以删除列表视图以从 Firestore 中删除数据【英文标题】:How to implement a swipe to delete listview to remove data from firestore 【发布时间】:2019-09-18 23:12:55 【问题描述】:

我对颤振和飞镖非常陌生,所以这可能是一个基本问题。但是,我想知道的是如何在列表视图中实现滑动删除方法以从 firestore 中删除数据。

我尝试使用 Dissmissible 功能,但我不明白如何显示列表,我似乎也不明白如何删除选定的数据。

这是我的飞镖代码

Widget build(BuildContext context) 
return new Scaffold(
  resizeToAvoidBottomPadding: false,
  appBar: new AppBar(
    centerTitle: true,
    automaticallyImplyLeading: false,
    title: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween,children: 
<Widget>[
      Text("INVENTORY",textAlign: TextAlign.center,) ,new IconButton(
          icon: Icon(
            Icons.home,
            color: Colors.black,
          ),
          onPressed: () 
            Navigator.push(
              context,
              SlideLeftRoute(widget: MyHomePage()),
            );
          )]),
  ),body: ListPage(),
);
  


 class ListPage extends StatefulWidget 
   @override
  _ListPageState createState() => _ListPageState();
  

class _ListPageState extends State<ListPage> 

Future getPosts() async
var firestore = Firestore.instance;

QuerySnapshot gn = await 
firestore.collection("Inventory").orderBy("Name",descending: 
false).getDocuments();

return gn.documents;



@override
Widget build(BuildContext context) 
return Container(
  child: FutureBuilder(
      future: getPosts(),
      builder: (_, snapshot)
    if(snapshot.connectionState == ConnectionState.waiting)
      return Center(
        child: Text("Loading"),
      );
    else

      return ListView.builder(
          itemCount: snapshot.data.length,
          itemBuilder:(_, index)
            return EachList(snapshot.data[index].data["Name"].toString(), 
snapshot.data[index].data["Quantity"]);
          );
    
  ),
 );
 



class EachList extends StatelessWidget
final String details;
final String name;
EachList(this.name, this.details);
@override
 Widget build(BuildContext context) 
// TODO: implement build
return new Card(
  child:new Container(
    padding: EdgeInsets.all(8.0),
    child: new Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
        new Row(
          children: <Widget>[
            new CircleAvatar(child: new Text(name[0].toUpperCase()),),
            new Padding(padding: EdgeInsets.all(10.0)),
            new Text(name, style: TextStyle(fontSize: 20.0),),
          ],
        ),
        new Text(details, style: TextStyle(fontSize: 20.0))
      ],
    ),
  ),
);
  


【问题讨论】:

【参考方案1】:

您应该使用 Dismissible 小部件。我将它用于从 Firestore 检索的收件箱列表。在您的 EachList 中返回类似这样的内容

return Dismissible(
        direction: DismissDirection.startToEnd,
        resizeDuration: Duration(milliseconds: 200),
        key: ObjectKey(snapshot.documents.elementAt(index)),
        onDismissed: (direction) 
          // TODO: implement your delete function and check direction if needed
          _deleteMessage(index);
        ,
        background: Container(
          padding: EdgeInsets.only(left: 28.0),
          alignment: AlignmentDirectional.centerStart,
          color: Colors.red,
          child: Icon(Icons.delete_forever, color: Colors.white,),
        ),
        // secondaryBackground: ..., 
        child: ...,
      );

    );

重要提示:为了删除列表项,您还需要从快照列表中删除该项目,而不仅仅是从 firestore 中删除:

_deleteMessage(index)
  // TODO: here remove from Firestore, then update your local snapshot list
  setState(() 
    snapshot.documents.removeAt(index);
  );

这里是文档:Implement Swipe to Dismiss

这里是 Flutter 团队的视频:Widget of the week - Dismissilbe

【讨论】:

它有效!非常感谢。我想知道如果我也想编辑详细信息该怎么做? 还有。 deleteMessage 函数有什么作用?【参考方案2】:

您可以使用flutter_slidable 包来实现相同的目的。

您还可以在 Github 上查看我的 Cricket Team,我在其中使用相同的包做了您想要实现的相同操作。

如何使用包的例子写在here。

【讨论】:

【参考方案3】:

我想补充一点,从 Firestore 中删除文档时,不需要 await,因为插件会自动缓存更改,然后在再次连接时同步它们。

比如我以前用过这个方法

  Future deleteWatchlistDocument(NotifierModel notifier) async 
    final String uid = await _grabUID();
    final String notifierID = notifier.documentID;
    return await _returnState(users.document(uid).collection(watchlist).document(notifierID).delete());
  

我正在等待呼叫通过,但是这阻止了任何其他呼叫通过并且只允许一个。删除这个await 标签解决了我的问题。

现在我可以离线删除文档,并且在重新连接后更改将与 Firestore 同步。在控制台中观看非常酷。

我建议观看this video about offline use with Firestore

【讨论】:

正如@Marco 提到的,从快照中删除文档也是明智之举。我只是使用 BLoC 来处理这个

以上是关于如何实现滑动以删除列表视图以从 Firestore 中删除数据的主要内容,如果未能解决你的问题,请参考以下文章

flutter-firestore:如何从列表视图中删除 n 天前的项目

滑动以从 TableView 中删除不起作用

手势识别器滑动以从核心数据中删除

如何实现左右滑动以更改 swift IOS 中的数据/视图?

在 Flutter 列表视图中删除 Firestore 数据

在 ViewPager 中捕获滑动以关闭列表视图手势