我想在flutter中使用提供程序显示来自Firestore的数据。我被卡住了,请帮助。以下是我的代码
//产品展示页
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shopping/pages/product_details.dart';
import 'package:shopping/provider/app_provider.dart';
class Product extends StatefulWidget {
@override
_ProductState createState() => _ProductState();
}
class _ProductState extends State<Product> {
@override
Widget build(BuildContext context) {
final product = Provider.of<AppProvider>(context);
return GridView.builder(
itemCount: productList.length,
gridDelegate:new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2),
itemBuilder: (BuildContext context, int index){
return Padding(
padding:const EdgeInsets.all(4.0),
child:SingleProd(
//where i want to get the product details
prodName: product.featuredProducts[index].name.toString(),
),
);
}
);
}
}
class SingleProd extends StatelessWidget {
final prodName;
final prodPicture;
final prodOldPrice;
final prodPrice;
SingleProd({this.prodName, this.prodPicture,this.prodOldPrice,this.prodPrice});
@override
Widget build(BuildContext context) {
return Card(
child: Hero(tag: new Text("hero 1"),
child:
Material( child: InkWell(
onTap: ()=>Navigator.of(context).push(new MaterialPageRoute(builder: (context)=>ProductDetails(
//here we are passing the value of the products to Product detail page
productDetailName:prodName,
)
)
),
child:GridTile(
footer: Container(
color: Colors.white,
child: new Row(
children: <Widget>[
new Expanded(
child: new Text(prodName, style: TextStyle(fontWeight: FontWeight.bold, fontSize:16.0),),
),
new Text(
"\$$prodPrice", style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold),)
],
)
),
child: Image.asset(prodPicture,
fit: BoxFit.cover,),
),
),
),
),
);
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/foundation.dart';
class Product{
static const ID = "id";
static const CATEGORY = "category";
static const NAME = "name";
static const PRICE = "price";
static const BRAND = "brand";
static const COLORS = "colors";
static const QUANTITY = "quantity";
static const SIZES = "sizes";
static const SALE = "sale";
static const FEATURED = "featured";
static const PICTURE = "picture";
String _id;
String _name;
String _brand;
String _category;
String _picture;
double _price;
int _quantity;
List _colors;
List _sizes;
bool _onSale;
bool _featured;
// getters
String get name => _name;
String get id => _id;
String get category => _category;
String get brand => _brand;
String get picture => _picture;
double get price => _price;
int get quantity => _quantity;
List get colors => _colors;
List get sizes => _sizes;
bool get onSale => _onSale;
bool get featured => _featured;
// named constructure
Product.fromSnapshot(DocumentSnapshot snapshot){
Map data = snapshot.data;
_name = data[NAME];
_id = data[ID];
_category = data[CATEGORY];
_brand = data[BRAND];
_price = data[PRICE];
_quantity = data[QUANTITY];
_colors = data[COLORS];
_onSale = data[SALE];
_featured = data[FEATURED];
_picture = data[PICTURE];
}
}
import 'package:flutter/material.dart';
import 'package:shopping/db/product.dart';
import 'package:shopping/models/product.dart';
class AppProvider with ChangeNotifier {
List<Product>_fearturedProducts=[];
//method
void _getFeaturedProducts()async{
_fearturedProducts=await _productService.getFeaturedProducts();
notifyListeners();
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:shopping/models/product.dart';
class ProductService{
Firestore _firestore=Firestore.instance;
String collection="Products";
Future<List<Product>>getFeaturedProducts(){
_firestore.collection(collection).where('featured', isEqualTo:true).getDocuments()
.then((snap){
List<Product>featuredProducts=[];
snap.documents.map((snapshot)=> featuredProducts.add(Product.fromSnapshot(snapshot)));
return featuredProducts;
});
}
}
答案 0 :(得分:1)
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shopping/pages/product_details.dart';
import 'package:shopping/provider/app_provider.dart';
import 'package:shopping/models/product.dart';
class Products extends StatefulWidget {
@override
ProductsState createState() => ProductsState();
}
class ProductsState extends State<Products> {
List<Product> products;
@override
Widget build(BuildContext context) {
final productProvider = Provider.of<CRUDModel>(context);
return StreamBuilder<QuerySnapshot>(
stream: productProvider.fetchProductsAsStream(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData) {
products = snapshot.data.documents
.map((doc) => Product.fromMap(doc.data, doc.documentID))
.toList();
return GridView.builder(
itemCount: products.length,
gridDelegate:new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:2),
itemBuilder: (BuildContext context, index){
return Padding(
padding:const EdgeInsets.all(4.0),
child:SingleProd(
product:products[index]
// prodPicture: productList[index]['picture'],
//prodOldPrice: productList[index]['oldPrice'],
//prodPrice: productList[index]['price'],
),
);
}
);
}
else {
return Text('fetching');
}
}
);
}
}
class SingleProd extends StatelessWidget {
//final prodName;
//final prodPicture;
//final prodOldPrice;
//final prodPrice;
final Product product;
SingleProd({ @required this.product});
//SingleProd({product.picture});
@override
Widget build(BuildContext context) {
return Card(
child: Hero(tag: product.id,
child:
Material( child: InkWell(
onTap: ()=>Navigator.of(context).push(new MaterialPageRoute(builder: (context)=>ProductDetails(
//here we are passing the value of the products to Product detail page
productDetailName:product.name,
productDetailNewPrice:product.price,
productDetailPicture:product.picture,
//productDetailOldPrice:prodOldPrice,
//productDetailNewPrice:prodPrice,
//productDetailPicture: prodPicture,
)
)
),
child:GridTile(
footer: Container(
color: Colors.white,
child: new Row(
children: <Widget>[
new Expanded(
child: new Text(product.name, style: TextStyle(fontWeight: FontWeight.bold, fontSize:16.0),),
),
new Text(
'${product.price} \$', style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold),)
],
)
),
child: Image.asset('assets/${product.picture}.jpg',
fit: BoxFit.cover,),
),
),
),
),
);
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'dart:ui';
class Product {
String id;
String name;
String brand;
String category;
String picture;
double price;
int quantity;
List colors;
List sizes;
bool sale;
bool featured;
Product(
{this.id, this.name, this.brand,
this.category, this.picture,this.price,
this.quantity,this.colors,this.sizes,this.sale,this.featured}
);
Product.fromMap(Map snapshot,String id) :
id = id ?? '',
name= snapshot['name'] ?? '',
brand = snapshot['brand'] ?? '',
category = snapshot['category'] ?? '',
picture= snapshot['picture'] ?? '',
price= snapshot['price'] ?? '',
quantity= snapshot['quantity'] ?? '',
colors= snapshot['colors'] ?? '',
sizes= snapshot['sizes'] ?? '',
sale= snapshot['sale'] ?? '',
featured= snapshot['featured'] ?? '';
toJson() {
return {
"name": name,
"brand": brand,
"category": category,
"picture": picture,
"price": price,
"quantity": quantity,
"colors": colors,
"sizes": sizes,
"sale": sale,
"featured": brand,
};
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:shopping/db/Api.dart';
import 'package:shopping/models/product.dart';
class CRUDModel extends ChangeNotifier {
//Api _api = locator<Api>();
String path="Products";
Api _api= Api();
List<Product> products;
Future<List<Product>> fetchProducts() async {
var result = await _api.getDataCollection();
products = result.documents
.map((doc) => Product.fromMap(doc.data, doc.documentID))
.toList();
notifyListeners();
return products;
}
Stream<QuerySnapshot> fetchProductsAsStream() {
notifyListeners();
return _api.streamDataCollection();
}
Future<Product> getProductById(String id) async {
var doc = await _api.getDocumentById(id);
notifyListeners();
return Product.fromMap(doc.data, doc.documentID) ;
}
}
import 'package:cloud_firestore/cloud_firestore.dart';
class Api{
final Firestore _db = Firestore.instance;
String ref="Products";
//CollectionReference ref;
/*Api({this.path } ) {
ref = _db.collection(path);
}*/
Future<QuerySnapshot> getDataCollection() {
//return ref.getDocuments() ;
return _db.collection(ref).where('featured', isEqualTo:true).getDocuments();
}
Stream<QuerySnapshot> streamDataCollection() {
// return ref.snapshots() ;
//return _db.snapshots(ref).getDocuments();
return _db.collection(ref).snapshots();
}
Future<DocumentSnapshot> getDocumentById(String id) {
// return ref.document(id).get();
return _db.document(id).get();
}
Future<void> removeDocument(String id){
//return ref.document(id).delete();
return _db.document(id).delete();
}
Future<DocumentReference> addDocument(Map data) {
// return ref.add(data);
return _db.collection(ref).add(data);
}
Future<void> updateDocument(Map data , String id) {
//return ref.document(id).updateData(data) ;
return _db.document(ref).updateData(data);
}
}
import 'package:flutter/material.dart';
import 'package:carousel_pro/carousel_pro.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:shopping/commons/common.dart';
import 'package:provider/provider.dart';
import 'package:shopping/provider/app_provider.dart';
import '../provider/user_provider.dart';
//My packages imports
import 'package:shopping/componets/horizontal_listview.dart';
import 'package:shopping/componets/product.dart';
import 'package:shopping/pages/cart.dart';
import 'package:shopping/pages/login.dart';
class HomePage extends StatefulWidget {
// List<Product> products;
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
TextEditingController _searchController = new TextEditingController();
//final FirebaseAuth _firebaseAuth=FirebaseAuth.instance;
@override
Widget build(BuildContext context) {
final user = Provider.of<UserProvider>(context);
final productProvider=Provider.of<CRUDModel>(context);
Widget image_carousel = new Container(
height: 200.0,
child: new Carousel(
boxFit: BoxFit.cover,
images: [
AssetImage('images/c1.jpg'),
AssetImage('images/m1.jpeg'),
AssetImage('images/m2.jpg'),
AssetImage('images/w1.jpeg'),
AssetImage('images/w3.jpeg'),
AssetImage('images/w4.jpeg'),
],
autoplay:true,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds:1000 ),
dotSize: 4.0,
indicatorBgPadding: 8.0,
dotBgColor: Colors.transparent,
),
);
return Scaffold(
appBar: new AppBar(
iconTheme: IconThemeData(color: blue),
elevation: 0.1,
backgroundColor: white,
title: Material(
borderRadius: BorderRadius.circular(20),
color: Colors.grey[50],
elevation: 0.0,
child: TextFormField(
controller: _searchController,
decoration: InputDecoration(
hintText: "Search",
border: InputBorder.none,
),
validator: (value) {
if (value.isEmpty) {
return "The Search field cannot be empty";
}
return null;
}),
),
actions: <Widget>[
new IconButton(
icon: Icon(
Icons.search,
color: blue,
),
onPressed: () {},
),
new IconButton(
icon: Icon(
Icons.shopping_cart,
color: blue,
),
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => new Cart()));
}),
],
),
drawer: new Drawer(
child: new ListView(
children: <Widget>[
//drawer header
new UserAccountsDrawerHeader(
accountName: Text("Afolabi"),
accountEmail: Text("mtreal62@gmail.com"),
currentAccountPicture: GestureDetector(
child: new CircleAvatar(
backgroundColor: Colors.grey,
child: Icon(
Icons.person,
color: Colors.white,
),
),
),
decoration: BoxDecoration(
color: blue,
),
),
//body
InkWell(
onTap: () {},
child: ListTile(
title: Text("Home Page"),
leading: Icon(
Icons.home,
color: blue,
),
),
),
InkWell(
onTap: () {},
child: ListTile(
title: Text("My Account"),
leading: Icon(
Icons.person,
color: blue,
),
),
),
InkWell(
onTap: () {},
child: ListTile(
title: Text("My Orders"),
leading: Icon(
Icons.shopping_basket,
color: blue,
),
),
),
InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => new Cart()));
},
child: ListTile(
title: Text("Shopping Cart"),
leading: Icon(
Icons.shopping_cart,
color: blue,
),
),
),
InkWell(
onTap: () {},
child: ListTile(
title: Text("Favourites"),
leading: Icon(
Icons.favorite,
color: blue,
),
),
),
Divider(),
InkWell(
onTap: () {},
child: ListTile(
title: Text("Settings"),
leading: Icon(
Icons.settings,
),
),
),
InkWell(
onTap: () {},
child: ListTile(
title: Text("About"),
leading: Icon(
Icons.help,
),
),
),
InkWell(
onTap: () {
user.signOut();
// changeScreenReplacement(context, Login());
},
child: ListTile(
title: Text("Log Out"),
leading: Icon(
Icons.transit_enterexit,
),
),
),
],
),
),
body: new Column(
children: <Widget>[
//Image Carousel for the home Page Banner
image_carousel,
//padding widget after carousel
new Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
alignment: Alignment.centerLeft,
child: new Text("Categories"),
),
),
//Horizontal layout start from here
HorizontalList(),
//End of the horizontal layout
//padding widget for Recent products categories
new Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
alignment: Alignment.centerLeft,
child: new Text("Recent Products"),
),
),
// Text(appProvider.featuredProducts.length.toString(),
//style: TextStyle(color: Colors.black),),
Flexible(
child: Products(),
),
//Horizontal layout start from here
],
),
);
}
}
Future _signOut() async {
try {
await FirebaseAuth.instance.signOut();
} catch (e) {
print(e); // TODO: show dialog with error
}
}
答案 1 :(得分:0)
您永远不会从_getFeaturedProducts()
类中调用AppProvider
。因此_fearturedProducts
将始终为空
答案 2 :(得分:0)