首页 > 解决方案 > Flutter 产品列表和使用 Firestore 的详细信息

问题描述

我正在努力为我遇到的这个问题找到明确的答案。我有两个屏幕,如下所示产品列表和产品详细信息。

在此处输入图像描述

第一个屏幕显示产品列表(Firebase 文档),当您单击某个项目时,它会将您带到产品详细信息屏幕。在产品显示屏幕上,您可以将产品标记为收藏,并具有上一个和下一个产品的导航按钮。

我的问题是我不知道应该使用FutureStream来实现这一目标。

使用 Future 出现问题如果我使用Future<List<Product>>我无法维护产品的书签状态,除非我每次为产品添加书签时都刷新产品列表。例如,如果说我已为产品 2 添加了书签,然后导航到产品 3,然后返回到产品 2,则不会保留书签状态。

使用 Stream的问题解决了维护书签状态的问题,但是我不知道如何管理产品之间的导航(上一个/下一个)

我有以下代码可以使用Stream导航到下一个产品

class SearchResultsBloc implements BlocBase {
  SearchResultsBloc() {
    DatabaseService().Search().listen((data) => _inList.add(data));
  }

  final _listController = BehaviorSubject<List<Product>>();
  Stream<List<Product>> get outList => _listController.stream;
  Sink<List<Product>> get _inList => _listController.sink;

 Stream<Product> outDetails(String uid) {
    return outList.map<Product>((results) => results
        .firstWhere((product) => product.uid == uid, orElse: () => null));
  }

}

下面这个方法检索下一个产品,但有人建议我不应该这样做,因为流可能会改变,而且我不知道如何禁用 <如果我正在查看第一个产品或禁用Next >上一个导航按钮如果我正在查看最后一个产品。

 Stream<Product> nextProduct(String uid) {
    var index = outList
        .map<int>(
            (results) => results.indexWhere((product) => product.uid == uid))
        .first
        .asStream();

    int nextIndex;
    index.listen((index) {
      nextIndex = index + 1;
    });

    return outList.map<Product>((results) => results.elementAt(nextIndex));
  }

标签: firebaseflutterdartgoogle-cloud-firestorestate-management

解决方案


使用StreamBuilder进行实时更改

StreamBuilder<QuerySnapshot>(
      stream:  FirebaseFirestore.instance.collection(Your collection).snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }

        return new ListView(
          children: snapshot.data.documents.map((DocumentSnapshot document) {
            return new ListTile(
              title: new Text(document.data()[key]),
              subtitle: new Text(document.data()[key]),
            );
          }).toList(),
        );
      },
    );

导航到下一页时,您必须传递 snapshot.data ,因此如果后端有任何更改,它将自动影响 UI。

您的outDetails方法看起来不错,但是当用户 onTap 特定listTile或您的自定义小部件时,您只需要传递 snapshot.data.document.data()


推荐阅读