flutter - 如何在我的 Flutter 中实现 Provider
问题描述
所以每当我尝试调用我的 AnnouncementScreen 页面时,我都会遇到这个错误:
在构建 AnnouncementScreen(dirty, dependencies: [_InheritedProviderScope]) 时抛出了以下断言:尝试使用具有 Listenable/Stream 子类型的 Provider(公告)。
这可能是一个错误,因为更新公告时提供者不会自动更新家属。相反,请考虑将 Provider 更改为处理更新机制的更具体的实现,例如:
- ListenableProvider
- ChangeNotifierProvider
- ValueListenableProvider
- 流提供者
或者,如果您正在制作自己的提供程序,请考虑使用 InheritedProvider。
如果您认为这不是错误,您可以通过null
在主文件中设置 Provider.debugCheckInvalidValueType 来禁用此检查:
void main() {
Provider.debugCheckInvalidValueType = null;
runApp(MyApp());
}
所以我有这个 Provider 叫 Announcements:
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import '../models/announcement_model.dart';
class Announcements with ChangeNotifier {
List _items = [];
String? token;
Announcements(this.token, this._items);
List get items {
return [..._items];
}
Future<void> fetchAnnouncements() async {
String url = "https://api-staging.xxx/announcements";
try {
final response = await http.get(
Uri.parse(url),
headers: {HttpHeaders.authorizationHeader: token!},
);
final extractedData = json.decode(response.body);
final List loadedProducts = [];
extractedData.forEach((prodId, data) {
loadedProducts.add(
Announcement(id: prodId, title: data['title'], body: data['body']));
});
_items = loadedProducts;
notifyListeners();
} catch (e) {
throw (e);
}
}
}
所以我有一个announcement_screen 基本上将所有项目数据从公告中提取到一个列表中。
这是我的 main.dart 文件(它返回这个 MultiProvider):
MultiProvider(
providers: [
ChangeNotifierProvider.value(
value: Auth(),
),
ProxyProvider<Auth, Announcements>(
update: (_, auth, previousProducts) => Announcements(
auth.token,
previousProducts == null ? [] : previousProducts.items,
),
),
],
child: Consumer<Auth>(
builder: (ctx, auth, _) => MaterialApp(
title: 'XXX',
theme: ThemeData(),
home: NavigationScreen(),
),
),
);
这就是我在announcement_screen.dart 中使用Provider 的方式(只关注Provider 的使用):
class AnnouncementScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final announcementData = Provider.of<Announcements>(context);
return Scaffold(
backgroundColor: Color(0xff1e1e1e),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
SizedBox(
height: 90,
),
Text(
'Good Morning, John',
style: TextStyle(
fontSize: 32,
fontFamily: 'Casper',
color: Color.fromRGBO(247, 245, 232, 1),
),
),
SizedBox(
height: 10,
),
Expanded(
child: SizedBox(
height: 200.0,
child: FutureBuilder(
future: Provider.of<Announcements>(context)
.fetchAnnouncements(),
builder: (ctx, snapshot) => snapshot.connectionState ==
ConnectionState.waiting
? Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: announcementData.items.length,
itemBuilder: (context, index) {
return Column(
children: [
_tile(announcementData.items[index].title,
announcementData.items[index].body),
Divider(
thickness: 4,
indent: 0,
endIndent:
MediaQuery.of(context).size.width / 1.4,
color: Color.fromRGBO(198, 158, 96, 1),
),
],
);
}),
),
),
),
DiamondButton(),
SizedBox(
height: 20,
)
],
),
),
),
);
}
}
解决方案
推荐阅读
- mysql - 插入具有不同列名的多行
- multithreading - Bukkit/Spigot - 如何等到 BukkitRunnable 完成
- java - 尝试编译要通过 JNI 从 Java 调用的 Go 共享对象时出错
- c# - 如何反序列化具有不正确重复结构的 json
- database - 将云中的数据库同步到本地以进行读取规模——如何触发同步?
- html - 矩形内圆响应内容
- c# - 添加或更新迁移时访问 Microsoft.Extensions.Hosting 服务时出错
- javascript - HTML5 Canvas Javascript - 如何使用“translate3d”制作带有瓷砖的可移动画布?
- ios - 在 Swift 中使用相同的顶级结构映射各种 JSON 响应
- python - REST API 发布请求导致请求成功但未创建