修改 Stream Builder 中的 Future Builder 以避免小部件闪烁

问题描述 投票:0回答:1

我在

FutureBuilder
中使用
StreamBuilder
,每次将文档添加到
activity
集合时都会更新 UI,以从 Firestore 获取一些附加数据。问题是,当 ConnectionState 正在等待时,
FutureBuilder
返回一个
SizedBox
小部件,导致所有卡片消失一秒钟。我想避免这种闪烁,因为它会给用户带来糟糕的用户界面体验。

有没有办法在活动流中查询所需的用户数据,以便所有数据立即返回,这样我就可以删除

FutureBuilder

如果没有......解决方案是什么?

    activityStream() {
      return FirebaseFirestore.instance
          .collection('activity')
          .orderBy('timestamp', descending: true)
          .limit(55)
          .snapshots();
    }

if (snapshot.connectionState == ConnectionState.waiting) {
                        return const SizedBox(
                          height: 65.0,
                        );
                      }

StreamBuilder<QuerySnapshot>(
      stream: activityStream(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        }

        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return const Center(child: CircularProgressIndicator());
          default:
            final activityContent = snapshot.data?.docs
                .map((data) => ActivityModel.fromFirestore(data))
                .toList();

            return Scrollbar(
              controller: widget.scrollController,
              child: ListView.builder(
                shrinkWrap: true,
                controller: widget.scrollController,
                itemCount: activityContent!.length,
                itemBuilder: (context, i) {

                  return FutureBuilder(
                    future: FirebaseFirestore.instance
                        .collection('users')
                        .where('uid', whereIn: activityContent[i].players)
                        .get(),

                    builder: (BuildContext context,
                        AsyncSnapshot<QuerySnapshot> snapshot) {
                      if (snapshot.connectionState == ConnectionState.waiting) {
                        return const SizedBox(
                          height: 65.0,
                        );
                      }

                      final users = snapshot.data!.docs.map((e) {
                        return UserModel.fromFirestore(e);
                      }).toList();

                      return MyWidget(
                        users: users,
                      );
                    },
                  );
                },
              ),
            );
        }
      },
    );

flutter google-cloud-firestore
1个回答
0
投票

我最近遇到了同样的问题,我通过用

StreamBuilder
包裹
StatefulWidget
来修复它,这样我就可以保留快照并在连接状态等待时使用它。

我的小部件看起来像这样:

class EventImages extends StatefulWidget {
  final String eventId;
  const EventImages({super.key, required this.eventId});

  @override
  State<EventImages> createState() => _EventImagesState();
}

class _EventImagesState extends State<EventImages> {
  AsyncSnapshot<QuerySnapshot>? lastSnapshot;

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: EventsDAL.getEventPhotosStream(widget.eventId),
      builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          if (lastSnapshot == null) {
            return const SizedBox.shrink();
          }
        }

        if (snapshot.hasError) {
          return Center(child: Text('Error loading images: ${snapshot.error}'));
        }

        if (snapshot.data!.docs.isEmpty) {
          return const SizedBox.shrink();
        }

        lastSnapshot = snapshot;

        return Padding(
          padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
          child: ConstrainedBox(
            constraints: const BoxConstraints(maxHeight: 340),
            child: GridView.builder(
                shrinkWrap: true,
                itemCount: lastSnapshot!.data!.docs.length,
                itemBuilder: (context, index) {
                  String imageUrl = lastSnapshot!.data!.docs[index]['url'];
                  return RoundedImage(
                    imageUrl: imageUrl,
                    size: 200,
                  );
                },
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3)),
          ),
        );
      },
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.