Firebase跨集合数据获取问题:跳转后无法加载busstops数据
解决BusInfo页面Timetable标签页展示busstops数据的问题
看起来你遇到的核心问题是把独立的Scaffold页面(Stations)嵌入到另一个Scaffold的TabBarView中导致的布局冲突,另外原有的CustomTable结构也可能引发嵌套滚动的问题。下面是一步步的解决方案:
1. 重构busstops数据展示组件
首先把Stations中负责加载和展示busstops的核心逻辑提取出来,去掉外层的Scaffold(因为BusInfo已经是一个完整的Scaffold,嵌套Scaffold会报错):
// 新的组件:只负责展示busstops列表,无外层Scaffold class BusStationsList extends StatelessWidget { // 如果需要按当前路线过滤站点,添加routenum参数 final String? routenum; BusStationsList({this.routenum}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(20.0), child: StreamBuilder<QuerySnapshot>( // 可选:如果busstops集合和routes关联,添加过滤条件 stream: routenum != null ? Firestore.instance.collection('busstops').where('routenum', isEqualTo: routenum).snapshots() : Firestore.instance.collection('busstops').snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasError) return Text('Error: ${snapshot.error}'); switch (snapshot.connectionState) { case ConnectionState.waiting: return Text('Loading....'); default: return ListView( children: snapshot.data!.documents.map((DocumentSnapshot document) { return CustomTable( title: document['title'], station1: document['station1'], station2: document['station2'], station3: document['station3'], station4: document['station4'], station5: document['station5'], station6: document['station6'], station7: document['station7'], station8: document['station8'], ); }).toList(), ); } }, ), ); } }
2. 优化CustomTable避免嵌套滚动
原CustomTable使用ListView会和外层的ListView冲突,改成Column来展示站点信息:
class CustomTable extends StatelessWidget { CustomTable({ required this.title, this.station1, this.station2, this.station3, this.station4, this.station5, this.station6, this.station7, this.station8, }); final title; final station1; final station2; final station3; final station4; final station5; final station6; final station7; final station8; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Center( child: Text( title, style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold, fontSize: 16), ), ), SizedBox(height: 8), // 只显示非空的站点 if (station1 != null) Text("- $station1"), if (station2 != null) Text("- $station2"), if (station3 != null) Text("- $station3"), if (station4 != null) Text("- $station4"), if (station5 != null) Text("- $station5"), if (station6 != null) Text("- $station6"), if (station7 != null) Text("- $station7"), if (station8 != null) Text("- $station8"), SizedBox(height: 16), // 站点组之间的间距 ], ); } }
3. 修改BusInfo页面嵌入新组件
把BusInfo中Timetable标签页的Icon(Icons.movie)替换成我们的BusStationsList,如果需要按当前路线过滤,记得传递routenum参数:
class BusInfo extends StatelessWidget { BusInfo({required this.routenum, this.from, this.to, this.via}); final routenum; final from; final to; final via; @override Widget build(BuildContext context) { return Scaffold( body: DefaultTabController( length: 2, child: Scaffold( appBar: AppBar( title: Text(routenum), backgroundColor: Color(0xFFBDBDBD), elevation: 3, bottom: TabBar( indicatorSize: TabBarIndicatorSize.label, tabs: [ Tab(child: Align(alignment: Alignment.center, child: Text("Route Info"))), Tab(child: Align(alignment: Alignment.center, child: Text("Timetable"))), ], ), ), body: TabBarView(children: [ Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text(routenum), Text(from), Text(via), Text(to), RaisedButton( child: Text('Back To HomeScreen'), color: Theme.of(context).primaryColor, textColor: Colors.white, onPressed: () => Navigator.pop(context), ), ], ), ), // 嵌入busstops列表组件,传递当前路线编号 BusStationsList(routenum: routenum), ]), ), ), ); } }
关键说明
- 移除嵌套Scaffold:Stations原来的Scaffold会和BusInfo的Scaffold冲突,导致布局报错,所以必须把展示逻辑提取成无Scaffold的子组件。
- 避免嵌套ListView:原CustomTable的ListView会和外层BusStationsList的ListView产生滚动冲突,改成Column更合适。
- 可选的路线过滤:如果你的busstops集合里有和routes对应的
routenum字段,添加where条件可以只加载当前路线的站点,提升用户体验。
内容的提问来源于stack exchange,提问作者Unknown Coder
相关产品推荐
相关产品推荐

