I have a code to display a list of images in a PageView with dots navigation. But for my project, I need to display several fields of the same document and this for each document of my Firebase collection. It seems that I need to put all my document as a List, don't know how to do that and can not figure out how to get each field of my doc then... Someone would have any idea ?
This is the code I use to display a list of images :
class SwipeImages extends StatefulWidget {
final List imageList;
const SwipeImages({
Key? key,
required this.imageList,
}) : super(key: key);
@override
_SwipeImagesState createState() => _SwipeImagesState();
}
class _SwipeImagesState extends State<SwipeImages> {
int _selectedPage = 0;
@override
Widget build(BuildContext context) {
return Container(
height: 500,
width: 500,
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
children: [
PageView(
onPageChanged: (num) {
setState(() {
_selectedPage = num;
});
},
children: [
for(var i=0; i < widget.imageList.length; i++)
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
),
child: Image.network(
"${widget.imageList[i]}",
fit: BoxFit.cover,
),
),
),
]
),
Positioned(
bottom: 20,
right: 0,
left: 0,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
for(var i=0; i < widget.imageList.length; i++)
AnimatedContainer(
duration: Duration(
milliseconds: 300
),
curve: Curves.easeInOutCubic,
width: _selectedPage == i ? 30.0 : 10.0,
height: 10.0,
margin: EdgeInsets.symmetric(
horizontal: 5,
),
decoration: BoxDecoration(
color: Black.withOpacity(0.4),
border: Border.all(
width: 0.25,
color: Black.withOpacity(0.6)
),
borderRadius: BorderRadius.circular(10)
),
),
],
),
),
]
),
),
);
}
}
class DisplayImages extends StatelessWidget {
@override
Widget build(BuildContext context) {
CollectionReference images = firestore.collection('Images');
return FutureBuilder(
future: product.doc('My Document').get(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if(snapshot.connectionState == ConnectionState.done) {
DocumentSnapshot<Object?> data = snapshot.data!;
List images = data['Images'];
// The field is an array with urls of the images I want to display;
return SwipeImages(imageList: images);
}
}
);
}
}
keeping it simple, why don't you pass the whole document you get from the FutureBuilder()
. This way, you can access all your fields(considering you have model classes, if not then you'll have to access fields using the .data
) without having to make a network call again.
Something like this,
DocumentSnapshot<Object?> data = snapshot.data!;
return SwipeImages(doc: data);//now you can use the whole separate doc and access all the fields.
If you need a constant stream of documents (multiple documents), then you'll have to use a stream. More info on https://dart.dev/tutorials/language/streams
Using Streambuilder -
StreamBuilder(
stream: stream,
builder: (BuildContext context,
AsyncSnapshot<List<DocumentSnapshot>> snapshots) {
if (snapshots.connectionState == ConnectionState.active &&
snapshots.hasData) {
print(snapshots.data);
return ListView.builder(
itemCount: snapshots.data.length,
itemBuilder: (BuildContext context, int index) {
DocumentSnapshot doc = snapshots.data[index];
return Text(
" Do anything with the stream of data",
);
},
);
} else {
return Center(child: CircularProgressIndicator());
}
},
),