I want to navigate from Products Page to a ProductDetail page but I am using data directly from firebase firestore. What do I put in the MaterialPageRoute as the arguments? I am also using StreamBuilder to get data snapshot from firebase. Below is the code. This is the products page.
class PopularRecipes extends StatefulWidget {
const PopularRecipes({Key key}) : super(key: key);
@override
_PopularRecipesState createState() => _PopularRecipesState();
}
class _PopularRecipesState extends State<PopularRecipes> {
final Stream _productStream =
FirebaseFirestore.instance.collection('products').snapshots();
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 20),
child: CustomText(
text: 'Popular Recipes',
size: 20,
),
),
Container(
height: 500,
child: StreamBuilder(
stream: _productStream,
builder: (context, snapshot) {
if (snapshot.data == null)
return Center(
child: CircularProgressIndicator(
backgroundColor: Colors.teal,
),
);
return ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) =>
_popularWidget(context, snapshot.data.docs[index]));
}),
),
],
);
}
Widget _popularWidget(BuildContext context, DocumentSnapshot document) {
return Stack(
children: [
Container(
margin: EdgeInsets.fromLTRB(40, 5, 20, 5),
height: 160,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(20)),
child: Padding(
padding: const EdgeInsets.fromLTRB(100, 20, 10, 20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
onTap: () => Navigator.push(context,
MaterialPageRoute(builder: (_) => DetailsScreen())),
child: Container(
width: 160,
child: Text(
document['name'],
style: TextStyle(
fontSize: 19.0, fontWeight: FontWeight.w600),
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
),
),
Column(
children: [
CustomText(
text: 'Ush.',
size: 14,
color: Colors.grey,
),
CustomText(
text: document['price'],
),
],
)
],
),
RatingBarIndicator(
rating: document['rating'].toDouble(),
itemBuilder: (context, index) => Icon(
Icons.star,
color: Colors.amber.shade200,
),
itemCount: 5,
itemSize: 15.0,
unratedColor: Colors.grey.shade300,
direction: Axis.horizontal,
),
SizedBox(
height: 10,
),
Container(
height: 40,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
Row(
children: [
for (var tag in document['tags'])
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: Colors.grey.shade200,
),
margin: EdgeInsets.only(right: 4),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0, vertical: 6),
child: Text(
tag.toString(),
style: TextStyle(
fontSize: 14,
),
textAlign: TextAlign.center,
),
),
)
],
),
],
),
),
],
),
),
),
Positioned(
top: 10,
left: 20,
bottom: 10,
child: GestureDetector(
onTap: () => Navigator.push(
context, MaterialPageRoute(builder: (_) => DetailsScreen())),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.network(
document['image'],
width: 110,
fit: BoxFit.cover,
),
),
),
)
],
);
}
}
This is the DetailsScreen page I want to go to when I click a specific product card.
class DetailsScreen extends StatefulWidget {
const DetailsScreen({Key key}) : super(key: key);
@override
_DetailsScreenState createState() => _DetailsScreenState();
}
class _DetailsScreenState extends State<DetailsScreen> {
@override
Widget build(BuildContext context) {
return Text(document['name']);
}
}
How do I pass data from the previous page to the details page with MaterialPageRoute when working with firebase data? Thank you.
In your DetailsScreen
page add the product variable
class DetailsScreen extends StatefulWidget {
final DocumentSnapshot product;
const DetailsScreen({Key key, @required this.product}) : super(key: key);
@override
_DetailsScreenState createState() => _DetailsScreenState();
}
class _DetailsScreenState extends State<DetailsScreen> {
@override
Widget build(BuildContext context) {
return Text(widget.product['name']);
}
}
And inside the onTap
:
GestureDetector(
onTap: () => Navigator.push(context,
MaterialPageRoute(builder: (_) => DetailsScreen(document))), //pass the product