首页 > 解决方案 > 流调用两次,listView数据变成重复

问题描述

我使用flutter_uploader将文件上传到服务器。我将监听器放在 main.dart 中。数据上传成功后,pageA中的listView会刷新。

主要.dart

 StreamSubscription<UploadTaskResponse> _subscription;

 @override
  void initState() {
    super.initState();
     _subscription = uploader.result.listen(
        (result) {
           _bloc.getData(..); // refresh in page A
    });
  }

pageA.dart

@override
  void initState() {
    super.initState();
    _bloc.getData(..); 
  }

@override
Widget build(BuildContext context) {
return Scaffold(
body:  StreamBuilder<List<ABC>>(
  stream: _bloc.abcStreem,
 if (snapshot.hasData) {
      // return listView code
    }
  )
    ...
 }

集团

Future refreshListView(...) async {
    List<ABC> abc;
    try {
      abc = await _repo.getList(...);
      abcSink.add(abc);
    } catch (e) {
      print('Caught $e');
    }
  }

当我在上传数据时切换到其他页面,然后切换回pageA,如果数据上传成功,有时会显示重复数据,并且同时调用pageA initState。

有什么办法可以防止吗?

标签: flutterlistviewdartstream-builder

解决方案


您的问题是您使用该方法将完整列表两次添加到您的 StreamabcSink.add(abc);

这是一个概念问题。

在这种情况下,当方法uploader.result.listen完成时,您不应再次检索整个列表,而应仅检索新创建的项目。
如果您可以隔离添加到列表中的新项目,您只需将其添加到您的流中

abcSink.add(myNewItemABC);

如果您无法检索单个项目,而您唯一的方法是检索整个列表,那么您将失去 Stream 的好处。
您应该考虑使用 FutureBuilder 而不是 StreamBuilder

FutureBuilder(
    future: refreshListView(),
    initialData: [],
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        return YOUR_LISTVIEW_CODE;

      }
    }
),

更新 refreshListView() 方法后可以_repo.getList(...);直接返回


推荐阅读