Flutter Provider 仅在热重载后显示结果
Posted
技术标签:
【中文标题】Flutter Provider 仅在热重载后显示结果【英文标题】:Flutter Provider showing results ONLY after Hot Reload 【发布时间】:2021-02-06 10:17:36 【问题描述】:我是初学者,我正在按照使用提供程序的教程构建应用程序。逻辑是,当您单击“类别”小部件时,它应该会引导您进入包含该类别产品的页面。逻辑按预期工作,除了我必须先刷新代码才能显示结果。坦率地说,我不知道自己做错了什么。
在主页中,类别小部件使用列表视图构建器呈现
Container(
height: 75,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: categoryProvider.categories.length,
itemBuilder: (context, index)
return GestureDetector(
onTap: () async
await productProvider.loadProductsByCategory(
categoryName:
categoryProvider.categories[index].name);
changeScreen(
context,
CategoryScreen(
categoryModel:
categoryProvider.categories[index]));
,
child: CategoriesWidget(
category: categoryProvider.categories[index]),
);
,
),
)
Main.Dart
我在听这样的供应商
void main()
WidgetsFlutterBinding.ensureInitialized();
runApp(MultiProvider(
providers: [
ChangeNotifierProvider.value(value: AppProvider()),
ChangeNotifierProvider.value(value: UserProvider.initialize()),
ChangeNotifierProvider.value(value: CategoryProvider.initialize()),
ChangeNotifierProvider.value(value: MarketProvider.initialize()),
ChangeNotifierProvider.value(value: ProductProvider.initialize()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Akatale',
theme: ThemeData(
primaryColor: Colors.black,
),
home: ScreenController())));
class ScreenController extends StatelessWidget
@override
Widget build(BuildContext context)
final auth = Provider.of<UserProvider>(context);
switch (auth.status)
case Status.Uninitialized:
return Loading();
case Status.UnAuthenticated:
case Status.Authenticating:
return SignInScreen();
case Status.Authenticated:
return MainScreen();
default:
return SignInScreen();
产品服务
有了这个,我按类别名称从 firestore 获取产品并将它们添加到列表中
class ProductService extends ChangeNotifier
String collection = "products";
Firestore _firestore = Firestore.instance;
Future<List<ProductModel>> getProductsByCategory(String category) async
List<ProductModel> products = [];
_firestore
.collection(collection)
.where("category", isEqualTo: category)
.getDocuments()
.then((result)
for (DocumentSnapshot product in result.documents)
products.add(ProductModel.fromSnapshot(product));
);
return products;
产品供应商
这里我有要在小部件中调用的公共方法
class ProductProvider with ChangeNotifier
ProductService _productService = ProductService();
List<ProductModel> products = [];
List<ProductModel> productsByCategory = [];
ProductProvider.initialize()
_loadProducts();
//Private method Load products to List
Future _loadProducts() async
products = await _productService.getProducts();
notifyListeners();
//public method to Load products to List by category
Future loadProductsByCategory(String categoryName) async
productsByCategory =
await _productService.getProductsByCategory(category: categoryName);
notifyListeners();
分类页面
这是根据所选类别呈现产品的位置
class CategoryScreen extends StatelessWidget
final CategoryModel categoryModel;
const CategoryScreen(Key key, this.categoryModel) : super(key: key);
@override
Widget build(BuildContext context)
final productProvider = Provider.of<ProductProvider>(context);
return Scaffold(
body: SafeArea(
child: ListView(
children: [
Text(categoryModel.name),
Column(
children: productProvider.productsByCategory.map((item)
return GestureDetector(
onTap: ()
//Load details page
,
child: ProductWidget(
product: item,
));
).toList(),
),
],
)),
);
显示一个空白页
但在点击热重载时,产品会出现
【问题讨论】:
如果我错了,请纠正我,但是通过浏览您的代码,我没有找到监听 ProductProvider 的小部件 你是对的。如果我认为是您的意思,我已经编辑了问题以添加该问题。我在 main.dart 文件中这样做 【参考方案1】:在您的ProductsService
中的getProductsByCategory
中,您不会等待getDocuments
。
因此,虽然文档将被加载,但它已经在模型中调用 notifyListeners,然后才真正完成加载它们。
因此,当您使用 hotreload 进行重建时,它们会出现
要解决这个问题,只需等待服务中的 getDocuments
【讨论】:
以上是关于Flutter Provider 仅在热重载后显示结果的主要内容,如果未能解决你的问题,请参考以下文章