0

我正在尝试创建一个列表,在其中拖动时可以删除其磁贴,因此我使用了 Dismissible 小部件,一切都按我的意愿工作,但是当拖动磁贴以将其关闭时,磁贴重新显示片刻并消失,我的意思的演示显示在这个视频中

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

我不确定问题出在哪里,任何帮助将不胜感激

4

2 回答 2

2

您应该避免在构建方法中分配未来。在 initState 中保存一个实例,因为每次构建树时都会再次调用未来。

Future myCachedFuture;
  @override
  void initState() {
    super.initState();

    myCachedFuture = getMyFavData();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(future: myCachedFuture,)
  }
于 2020-05-23T23:07:38.150 回答
1

您曾经FutureBuilder获取数据列表并将其onDismissed删除。

当您关闭一个项目时,保存它的小部件将再次重建,因此您无需调用setState.

此外,当您调用删除函数(deleteFromDataBase)时,这将删除一些实际保存的数据,因此您不需要从您获取的数据中删除它,因为这里当一个项目被删除时,将调用一个函数从实际保存的数据中删除它同样,小部件将被重建,并且另一个调用(getMyFavData())将发生在保存的数据上以获取它们,但这次结果是前一个没有删除项目的所有结果。

我用你的代码做了一个简单的例子,并做了一个假的未来电话:

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

于 2020-05-23T23:06:32.753 回答