如何使用 Flutter/Dart 根据选择将单个 Firestore 文档 ID 传递给另一个类?

Par*_*erd 2 dart flutter google-cloud-firestore

我正在尝试使用 flutter 设计一个功能,当用户选择旅行的缩略图时,它会将用户带到一个页面,其中包含他们选择的旅行的更多详细信息。我试图尽可能少地查询 Firestore 数据库,因此我试图从单个查询快照中获取文档 ID 并将其传递给 individualTripPackage 类。我已经尝试过很多方法这种方法,但都失败了。我还查看了人们在 SO 上发布的其他解决方案,但我无法让它们适用于我的具体案例。我究竟做错了什么?我是颤振的新手,因此如果您对其他方法或更有效的解决方案有想法,我愿意接受建议。

旅行套餐类别:

class _TripPackagesState extends State<TripPackages> {
  @override
  Widget build(BuildContext context) {
 //Some other code......
            child: SingleChildScrollView(
              child: StreamBuilder<QuerySnapshot>(
                stream:
                    Firestore.instance.collection('trip_package').snapshots(),
                builder: (BuildContext context,
                    AsyncSnapshot<QuerySnapshot> docSnapshot) {
                  if (!docSnapshot.hasData) return const Text('Loading...');
                  final int docCount = docSnapshot.data.documents.length;
                  return GridView.builder(
                    shrinkWrap: true,
                    primary: false,
                    scrollDirection: Axis.vertical,
                    itemCount: docCount,
                    itemBuilder: (_, int index) {
                      DocumentSnapshot document =
                          docSnapshot.data.documents[index];
                      return GestureDetector(
                        onTap: () => Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (_) => IndividualTripPackage(
                                docID: docSnapshot.data.documents[index]),
                          ),
    //Some other code .....
  }
}
Run Code Online (Sandbox Code Playgroud)

个人旅行套餐类别:

class IndividualTripPackage extends StatefulWidget {
  DocumentSnapshot docID;
  IndividualTripPackage({this.docID});
  @override
  _IndividualTripPackageState createState() => _IndividualTripPackageState();
}

class _IndividualTripPackageState extends State<IndividualTripPackage> {
  @override
  Widget build(BuildContext context) {
    final String docID = widget.docID.data['docID'];
    return Material(
      child: SafeArea(
        child: LayoutBuilder(
          builder: (BuildContext context, BoxConstraints viewportConstraints) {
            return SingleChildScrollView(
              child: ConstrainedBox(
                constraints: BoxConstraints(minHeight: viewportConstraints.maxHeight),
                child: StreamBuilder(
                    stream: Firestore.instance.collection('trip_package').document('docID').snapshots(),
                    builder: (context, snapshot) {
                      if (!snapshot.hasData) {
                        return Text('Loading data....Please wait...');
                      } else {
                        final int itemCount = snapshot.data.document('docID').data['itineraryItems'].length;
                        return Column(...);
                      }
                    }),
      //Some more code........
  }
}
Run Code Online (Sandbox Code Playgroud)

Wil*_*las 5

好吧,我希望这能回答你的问题!

我一直在我的应用程序中使用这样的方法,它似乎对我有用。当然,您会想要根据自己的喜好调整类名称和其他代码,但希望这就是您想要做的。

旅行缩略图

import 'package:flutter/material.dart';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:my_test_project/screens/detail.dart';

class Thumbnail extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _ThumbnailState();
}

class _ThumbnailState extends State<Thumbnail> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: false,
        title: Text(
          'Thumbnail'
        ),
      ),
      body: ListView(
        children: <Widget>[
          StreamBuilder<QuerySnapshot>(
            stream: Firestore.instance.collection('trips').snapshots(),
            builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
              if (snapshot.hasError) return Text('Error: ${snapshot.error}');
              if (!snapshot.hasData) return Container(
                child: Center(
                  child: CircularProgressIndicator()
                ),
              );
              return Column(
                children: snapshot.data.documents.map((doc) {
                  return GestureDetector(
                    onTap: () {
                      var docId = doc.documentID;
                      Navigator.push(context, MaterialPageRoute(builder: (context) => Detail(docId)));
                    },
                    child: Container(
                      child: Image(
                        image: NetworkImage(
                          doc.data['photo']
                        ),
                      ),
                    ),
                  );
                }).toList(),
              );
            },
          )
        ],
      )
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

行程详情

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class Detail extends StatefulWidget {

  final docId;
  Detail(this.docId);

  @override
  State<StatefulWidget> createState() => _DetailState(docId);
}

class _DetailState extends State<Detail> {

  final docId;
  _DetailState(this.docId);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'Detail'
        ),
      ),
      body: ListView(
        children: <Widget>[
          StreamBuilder<DocumentSnapshot>(
            stream: Firestore.instance.collection('trips').document(docId).snapshots(),
            builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
              if (snapshot.hasError) return Text('Error: ${snapshot.error}');
              if (!snapshot.hasData) return Container(
                child: Center(
                  child: CircularProgressIndicator()
                ),
              );
              return Column(
                children: <Widget>[
                  Container(
                    child: Text(
                      snapshot.data['title'],
                      style: TextStyle(
                        fontSize: 24.0
                      ),
                    ),
                  ),
                  Container(
                    child: Image(
                      image: NetworkImage(
                        snapshot.data['photo']
                      ),
                    ),
                  ),
                  Container(
                    child: Text(
                      snapshot.data['body']
                    )
                  )
                ],
              );
            },
          )
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

基本上,我将一个变量传递到下一个屏幕,该屏幕具有用于 DocumentSnapshot 流的文档 ID。