FirebaseAnimatedList显示逻辑优化:按需展示用户ID存在状态
问题描述
使用FirebaseAnimatedList从Firebase实时数据库获取数据,需求如下:
- 若用户ID存在于1个或多个数据库节点中,按存在节点的数量展示对应次数的“Your id exist”,不存在的节点不输出内容
- 若用户ID在所有节点中都不存在,仅展示1次“Your id does not exist”
当前实现逻辑存在问题:数据库有3个子节点时,ID不存在会重复输出3次“Your id does not exist”;ID存在于1个节点时,会同时输出1次存在和2次不存在。
以下是当前代码实现:
import 'package:bidding/global/global_variable.dart'; import 'package:bidding/screen/productDetail/product_detail.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:firebase_database/ui/firebase_animated_list.dart'; import 'package:flutter/material.dart'; class MyAnimatedList extends StatefulWidget { final DatabaseReference dbRef; final String category; const MyAnimatedList( {super.key, required this.dbRef, required this.category}); @override State<MyAnimatedList> createState() => _MyAnimatedListState(); } class _MyAnimatedListState extends State<MyAnimatedList> { @override Widget build(BuildContext context) { return SizedBox( height: 200, child: FirebaseAnimatedList( scrollDirection: Axis.horizontal, query: widget.dbRef, itemBuilder: (context, snapshot, animation, index) { final userId = snapshot.child('userid').value.toString(); Map dbDetail = snapshot.value as Map; dbDetail[Key] = snapshot.key; if (userId == uid) { return Text("Your id exist"); } else { return Text( "Your id does not exist", style: TextStyle( fontSize: 15, fontWeight: FontWeight.w500, color: cRed, ), ); } }), ); } }
解决方案
可以通过FirebaseAnimatedList结合StreamBuilder实现需求,核心思路是先判断全局是否存在匹配ID,再针对性渲染内容:
修改后的代码如下:
import 'package:bidding/global/global_variable.dart'; import 'package:bidding/screen/productDetail/product_detail.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:firebase_database/ui/firebase_animated_list.dart'; import 'package:flutter/material.dart'; class MyAnimatedList extends StatefulWidget { final DatabaseReference dbRef; final String category; const MyAnimatedList( {super.key, required this.dbRef, required this.category}); @override State<MyAnimatedList> createState() => _MyAnimatedListState(); } class _MyAnimatedListState extends State<MyAnimatedList> { @override Widget build(BuildContext context) { return SizedBox( height: 200, child: StreamBuilder<DatabaseEvent>( stream: widget.dbRef.onValue, builder: (context, snapshot) { // 数据库无数据时直接返回不存在提示 if (!snapshot.hasData || snapshot.data?.snapshot.value == null) { return const Text("Your id does not exist", style: TextStyle( fontSize: 15, fontWeight: FontWeight.w500, color: Colors.red, )); } // 遍历所有节点,判断是否存在匹配的用户ID Map<dynamic, dynamic> data = snapshot.data!.snapshot.value as Map; bool hasMatchingId = data.values.any((item) => item['userid'] == uid); if (!hasMatchingId) { // 所有节点都不匹配,显示一次提示 return const Text("Your id does not exist", style: TextStyle( fontSize: 15, fontWeight: FontWeight.w500, color: Colors.red, )); } else { // 存在匹配节点,仅渲染匹配项 return FirebaseAnimatedList( scrollDirection: Axis.horizontal, query: widget.dbRef, itemBuilder: (context, itemSnapshot, animation, index) { final userId = itemSnapshot.child('userid').value.toString(); Map dbDetail = itemSnapshot.value as Map; dbDetail[Key] = itemSnapshot.key; // 匹配节点返回提示文本,不匹配节点返回空容器 if (userId == uid) { return FadeTransition( opacity: animation, child: const Text("Your id exist"), ); } else { return const SizedBox.shrink(); } }, ); } }, ), ); } }
逻辑说明
- 通过
StreamBuilder监听数据库节点的完整数据快照,先全局判断是否存在匹配的用户ID - 若不存在匹配ID,直接返回单次提示文本
- 若存在匹配ID,使用
FirebaseAnimatedList,仅对匹配的节点返回“Your id exist”,不匹配节点返回空容器(不占用布局空间) - 保留
FadeTransition维持FirebaseAnimatedList的原生动画效果
内容的提问来源于stack exchange,提问作者Mubashar Ishaq
相关产品推荐
相关产品推荐

