How to manage two ListView with data in firestore in the same screen in Flutter
572
In order to read both info from the same Stream
you need to expose it as a broadcast stream first:
final streamQuery = _firestore
.collection('books')
.snapshots()
.asBroadcastStream();
return StreamBuilder<QuerySnapshot>(
stream: streamQuery,
builder: ...
Author by
M4trix Dev
Updated on December 14, 2022Comments
-
M4trix Dev over 1 year
I am building a Flutter app and I have a screen with 2 ListViews. The data source is a firestore database and it is the same for both list however one list presents only an image while the other list presents the image PLUS other information.
I have managed to found a solution to display both List however it does not seem the most effective because I believe I am downloading the same data 2 time. Do you have any suggestion on how to make it better???
See my code below
final _firestore = Firestore.instance; class ItemPage extends StatefulWidget { @override _ItemPageState createState() => _ItemPageState(); } class _ItemPageState extends State<ItemPage> { bool showSpinner = false; @override Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( heroTag: 'itemppage', transitionBetweenRoutes: false, middle: Text( appData.categoryName, style: kSendButtonTextStyle, ), ), child: Scaffold( backgroundColor: kColorPrimary, body: ModalProgressHUD( inAsyncCall: showSpinner, child: Column( children: <Widget>[ Expanded( child: ItemList(), ), Container( height: 80.0, child: ItemListBottomScroll(), ) ], ), ), ), ); } } class ItemList extends StatelessWidget { @override Widget build(BuildContext context) { return StreamBuilder<QuerySnapshot>( stream: _firestore .collection('books') .snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasError) return new Text('Error: ${snapshot.error}'); switch (snapshot.connectionState) { case ConnectionState.waiting: return new Text( 'Loading...', style: kSendButtonTextStyle, ); default: return new PageView( scrollDirection: Axis.horizontal, children: snapshot.data.documents.map((DocumentSnapshot document) { return SingleChildScrollView( child: Column( children: <Widget>[ Container( margin: EdgeInsets.all(10.0), child: Stack( children: <Widget>[ CachedNetworkImage( imageUrl: document['url'], placeholder: (context, url) => new CircularProgressIndicator(), errorWidget: (context, url, error) => new Icon(Icons.error), width: MediaQuery.of(context).size.width - 20, height: (MediaQuery.of(context).size.width - 20), fit: BoxFit.cover), Positioned( bottom: 0.0, right: 0.0, child: IconButton( color: kColorAccent.withOpacity(0.8), iconSize: 50.0, icon: Icon(Icons.add_circle), onPressed: () { print(document['name'] + document.documentID + ' clicked'); }, ), ), ], ), ), Padding( padding: const EdgeInsets.only( left: 10.0, right: 10.0, bottom: 10.0), child: Row( children: <Widget>[ Expanded( child: Text( document['name'], style: kSendButtonTextStyle, ), flex: 3, ), Expanded( child: Text( appData.currency + document['price'], textAlign: TextAlign.right, style: kDescriptionTextStyle, ), flex: 1, ), ], ), ), Padding( padding: const EdgeInsets.only(left: 10.0, right: 10.0), child: Container( child: Text( document['description'], style: kDescriptionTextStyle, ), width: double.infinity, ), ) ], ), ); }).toList(), ); } }, ); } } class ItemListBottomScroll extends StatelessWidget { @override Widget build(BuildContext context) { return StreamBuilder<QuerySnapshot>( stream: _firestore .collection('books') .snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasError) return new Text('Error: ${snapshot.error}'); switch (snapshot.connectionState) { case ConnectionState.waiting: return new Text('Loading...'); default: return new ListView( scrollDirection: Axis.horizontal, children: snapshot.data.documents.map((DocumentSnapshot document) { return Stack( children: <Widget>[ Container( height: 80.0, width: 90.0, padding: EdgeInsets.only(left: 10.0), child: GestureDetector( onTap: () { print(document['name'] + document.documentID + ' bottom clicked'); }, child: new CachedNetworkImage( imageUrl: document['url'], placeholder: (context, url) => new CircularProgressIndicator(), errorWidget: (context, url, error) => new Icon(Icons.error), fit: BoxFit.cover), ), ), ], ); }).toList(), ); } }, ); } }