无法在 flutter 中正确循环获取的 firestore 数据并将其显示在选项卡中
Can not properly loop through the fetched firestore data in flutter and display it in Tabs
我正在尝试使用 StreamBuilder
遍历获取的数据并将其推送到 TabController
。
问题是在 TabController
中我需要设置 length
属性。在我的例子中,它将是 3,但理想情况下,它应该根据 collection
.
中的 documents
的数量动态计算
然后在我的 TapBar
中有 tabs
属性,它看起来应该是这样的:
final List<Widget> myTabs = [
Tab(text: 'Tab 1'),
Tab(text: 'Tab 2'),
Tab(text: 'Tab 3'),
];
所以我试图在 StreamBuilder
:
中生成 myTabs
列表
final List<Widget> finalTabs = [];
Timestamp eventTabControl = snapshot.data?.docs[index].data()['day'];
finalTabs.addAll([Tab(text: eventTabControl.toDate().toString())]);
但它没有像我预期的那样工作。它只为我生成 1 个选项卡而不是 3 个。
预期结果是:
然而,当我尝试在控制台中打印 finalTabs
时,它会显示我所有的 3 个值。
我的全部代码是:
import 'package:book_club/config/palette.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class EventTabControl extends StatefulWidget {
const EventTabControl({Key? key}) : super(key: key);
@override
State<EventTabControl> createState() => _EventTabControlState();
}
class _EventTabControlState extends State<EventTabControl>
with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
void initState() {
_tabController = TabController(length: 1, vsync: this);
_tabController.addListener(_handleTabSelection);
super.initState();
}
_handleTabSelection() {
if (_tabController.indexIsChanging) {
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection("schedule").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: snapshot.data?.docs.length,
itemBuilder: (_, index) {
final List<Widget> finalTabs = [];
Timestamp eventTabControl =
snapshot.data?.docs[index].data()['day'];
finalTabs
.addAll([Tab(text: eventTabControl.toDate().toString())]);
return Container(
child: Container(
child: TabBar(
controller: _tabController,
indicatorWeight: 2.5,
indicatorSize: TabBarIndicatorSize.tab,
labelColor: Palette.custGreen,
unselectedLabelColor: Palette.custBlue,
indicator: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Palette.custGreen,
width: 2.0,
),
),
),
tabs: finalTabs,
),
),
);
});
}
},
);
}
}
这只是TabController的一个逻辑。
您正在使用不合适的 ListView Builder,因为它会根据您的情况单独呈现您的小部件 3 次,相反,您可以动态 return 选项卡,
你的其他部分:
else { final List<Widget> finalTabs = [];
snapshot.data?.docs.forEach((document){
Timestamp eventTabControl = document.data()['day'];
finalTabs.add(eventTabControl.toDate().toString());
}
);
return Container(
child: TabBar(
controller: _tabController,
indicatorWeight: 2.5,
indicatorSize: TabBarIndicatorSize.tab,
labelColor: Palette.custGreen,
unselectedLabelColor: Palette.custBlue,
indicator: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Palette.custGreen,
width: 2.0,
),
),
),
tabs: finalTabs.isEmpty
? <Widget>[]
: finalTabs.map((dynamicContent) {
return new Text('your contentContent')),
);
}).toList(),
),
);
}
我正在尝试使用 StreamBuilder
遍历获取的数据并将其推送到 TabController
。
问题是在 TabController
中我需要设置 length
属性。在我的例子中,它将是 3,但理想情况下,它应该根据 collection
.
documents
的数量动态计算
然后在我的 TapBar
中有 tabs
属性,它看起来应该是这样的:
final List<Widget> myTabs = [
Tab(text: 'Tab 1'),
Tab(text: 'Tab 2'),
Tab(text: 'Tab 3'),
];
所以我试图在 StreamBuilder
:
myTabs
列表
final List<Widget> finalTabs = [];
Timestamp eventTabControl = snapshot.data?.docs[index].data()['day'];
finalTabs.addAll([Tab(text: eventTabControl.toDate().toString())]);
但它没有像我预期的那样工作。它只为我生成 1 个选项卡而不是 3 个。
预期结果是:
然而,当我尝试在控制台中打印 finalTabs
时,它会显示我所有的 3 个值。
我的全部代码是:
import 'package:book_club/config/palette.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class EventTabControl extends StatefulWidget {
const EventTabControl({Key? key}) : super(key: key);
@override
State<EventTabControl> createState() => _EventTabControlState();
}
class _EventTabControlState extends State<EventTabControl>
with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
void initState() {
_tabController = TabController(length: 1, vsync: this);
_tabController.addListener(_handleTabSelection);
super.initState();
}
_handleTabSelection() {
if (_tabController.indexIsChanging) {
setState(() {});
}
}
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance.collection("schedule").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemCount: snapshot.data?.docs.length,
itemBuilder: (_, index) {
final List<Widget> finalTabs = [];
Timestamp eventTabControl =
snapshot.data?.docs[index].data()['day'];
finalTabs
.addAll([Tab(text: eventTabControl.toDate().toString())]);
return Container(
child: Container(
child: TabBar(
controller: _tabController,
indicatorWeight: 2.5,
indicatorSize: TabBarIndicatorSize.tab,
labelColor: Palette.custGreen,
unselectedLabelColor: Palette.custBlue,
indicator: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Palette.custGreen,
width: 2.0,
),
),
),
tabs: finalTabs,
),
),
);
});
}
},
);
}
}
这只是TabController的一个逻辑。
您正在使用不合适的 ListView Builder,因为它会根据您的情况单独呈现您的小部件 3 次,相反,您可以动态 return 选项卡,
你的其他部分:
else { final List<Widget> finalTabs = [];
snapshot.data?.docs.forEach((document){
Timestamp eventTabControl = document.data()['day'];
finalTabs.add(eventTabControl.toDate().toString());
}
);
return Container(
child: TabBar(
controller: _tabController,
indicatorWeight: 2.5,
indicatorSize: TabBarIndicatorSize.tab,
labelColor: Palette.custGreen,
unselectedLabelColor: Palette.custBlue,
indicator: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Palette.custGreen,
width: 2.0,
),
),
),
tabs: finalTabs.isEmpty
? <Widget>[]
: finalTabs.map((dynamicContent) {
return new Text('your contentContent')),
);
}).toList(),
),
);
}