0

我有一个列表视图,其中每个项目都是来自 firestore 集合的一个文档。我想点击该项目并将文档信息传递到详细信息页面。

这就是我在第一个流中检索文档信息的方式:

child: Text(streamSnapshot.data.docs[index]['event_title'],

这就是我尝试将数据发送到下一页的方式:

child: GestureDetector(
                          onTap: () {
                            Navigator.pushNamed(context, EventPage.id, arguments: streamSnapshot.data.docs[index]);
                          },

我不知道如何接收传递的数据:

    class _EventPageState extends State<EventPage> {
  @override

final db = FirebaseFirestore.instance;
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!.settings.arguments;
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('event_title'),
      ),
      child: Column(

我知道在下一页我需要一个 StreamBuilder,但是您对如何使该流仅显示传入的文档有任何见解吗?

4

2 回答 2

0

你为什么不使用 Provider 呢?它将帮助您避免样板文件,并且当您使用流时,它将让您以更好的方式处理信息。在这里查看

于 2021-08-16T23:52:33.943 回答
0

我已经制定了这个问题的答案。我确信有几种方法可以做到这一点,但这是我的:

关键是将firestore文档ID传递到下一页。在此示例代码中,我将streamSnapshot.data.docs[index].id.toString()作为参数传递给自定义小部件。我已经在该小部件中找到了我的命名路线。

StreamBuilder(
    stream: FirebaseFirestore.instance
        .collection('events')
        .where('start_date', isGreaterThanOrEqualTo: DateTime.now())
        .snapshots(),
    builder: (context, AsyncSnapshot streamSnapshot) {

      if (!streamSnapshot.hasData) {
        return SizedBox(
          height: 250,
          child: Center(
            child: CircularProgressIndicator(),
          ),
        );
      } else
        return SizedBox(
          height: 250,
          child: ListView.builder(
            scrollDirection: Axis.horizontal,
            itemCount: streamSnapshot.data.docs.length,
            itemBuilder: (ctx, index) =>

                EventListHorizontalTile(

                //passes the document ID as a string down to the horizontally scrollable tile,
                //where we push a named route with the docID string as an argument

                firestoreDocID: streamSnapshot.data.docs[index].id.toString(),

                  image: streamSnapshot.data.docs[index]['main_image'],
                  name: streamSnapshot.data.docs[index]['name'],
              ),
          ),
        );
    }),

然后我创建了一个类,通过命名路由作为参数传递。

class Events {
  final String firestoreDocID;

  Events({
    required this.firestoreDocID,

  });

}

现在,在我的EventListHorizontalTile小部件中:

class EventListHorizontalTile extends StatelessWidget {
  const EventListHorizontalTile({
    Key? key,

    required this.name,
    this.firestoreDocID = '',

  }) : super(key: key);

  final String name;
  final String firestoreDocID;

  @override
  Widget build(BuildContext context) {
return GestureDetector(

        onTap: () {

//Here I am pushing a named route with an argument, using that Events class I made earlier.

          Navigator.pushNamed(context, EventPage.id, arguments: Events(firestoreDocID: firestoreDocID));

        },

//child: The rest of the list tile widget

),

现在我们必须在 中编写一些代码EventPage来接收参数。

class EventPage extends StatefulWidget {
  const EventPage({
    Key? key,
  }) : super(key: key);

  static String id = 'EventPage';

  @override
  _EventPageState createState() => _EventPageState();
}

class _EventPageState extends State<EventPage> {
  @override
  Widget build(BuildContext context) {


//This is how we receive the argument.
    final args = ModalRoute.of(context)!.settings.arguments as Events;

    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(),
      child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [

//Some text to see if the string made it.
            Text(args.firestoreDocID),

]),
),
);
}
}

就是这样!在新页面中获得该文档 ID 后,您可以Streambuilder这样调用:

StreamBuilder(
              stream: FirebaseFirestore.instance
                  .collection('events')
                  .doc(args.firestoreDocID)
                  .snapshots(),
于 2021-10-02T02:00:35.647 回答