Flutter Flatter FutureProvider执行构建两次
我已经从使用Flutter Flatter FutureProvider执行构建两次,flutter,Flutter,我已经从使用initState获取数据和Futurebuilder将其加载到Futureprovider的Statefulwidget进行了更改。但似乎Futureprovider是两次执行build方法,而我以前的方法只执行了一次。这种行为正常吗 class ReportsPage extends StatelessWidget { const ReportsPage({Key key}) : super(key: key); @override Widget build(Bui
initState
获取数据和Futurebuilder
将其加载到Futureprovider
的Statefulwidget
进行了更改。但似乎Futureprovider
是两次执行build
方法,而我以前的方法只执行了一次。这种行为正常吗
class ReportsPage extends StatelessWidget {
const ReportsPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureProvider<List<ReportModel>>(
create: (_) async => ReportsProvider().loadReportData(1),
initialData: null,
catchError: (_, __) => null,
child: const ReportWidg()
);
}
}
class ReportWidg extends StatelessWidget {
const ReportWidg();
@override
Widget build(BuildContext context) {
print("Execute Build");
final reportList = Provider.of<List<ReportModel>>(context);
if (reportList == null) {
return Center(child: CircularProgressIndicator());
} else if (reportList.isEmpty) {
return Center(child: Text("Det finns inga rapporter."));
}
print(reportList.length);
return Container();
}
}
class ReportsPage扩展了无状态小部件{
const ReportsPage({Key}):super(Key:Key);
@凌驾
小部件构建(构建上下文){
返回未来提供者(
创建:(41; async=>ReportsProvider().loadReportData(1),
initialData:null,
catchError:(u,u)=>null,
子项:const ReportWidg()
);
}
}
类ReportWidg扩展了无状态小部件{
const ReportWidg();
@凌驾
小部件构建(构建上下文){
打印(“执行构建”);
最终报告列表=提供者(上下文);
if(reportList==null){
返回中心(子项:CircularProgressIndicator());
}else if(reportList.isEmpty){
返回中心(儿童:文本(“Det finns inga Reporter”);
}
打印(reportList.length);
返回容器();
}
}
我对flift相对来说是个新手,但我认为这是因为无状态小部件
是@不可变的
,这意味着无论什么时候发生变化,它都需要重建自身
在第一次构建时,进行了async
调用,并呈现了ReportWidg()
然后这一行final reportList=Provider.of(context)代码>获取新获取的数据作为异步
函数的结果,因此不可变
小部件需要重建自身,因为它不能“更改”
在面向对象和函数式编程中,一种不可变的对象
(不可更改对象)是其状态无法修改的对象
在它被创建之后。。。这与可变对象形成对比
(可更改对象),创建后可对其进行修改
还是我错了?我对颤振相对来说是个新手,但我认为这是因为无状态widget
是@不可变的,这意味着无论什么时候发生变化,它都需要重建自身
在第一次构建时,进行了async
调用,并呈现了ReportWidg()
然后这一行final reportList=Provider.of(context)代码>获取新获取的数据作为异步
函数的结果,因此不可变
小部件需要重建自身,因为它不能“更改”
在面向对象和函数式编程中,一种不可变的对象
(不可更改对象)是其状态无法修改的对象
在它被创建之后。。。这与可变对象形成对比
(可更改对象),创建后可对其进行修改
还是我错了?我怀疑您的FutureProvider应该被提升到一个单一的实例化中,就像放在任何build()方法之外的全局变量中一样。这当然会缓存结果,因此您可以通过让值依赖于正在监视的其他提供程序()或通过FutureProvider.family将其设置为重新生成。我怀疑您的FutureProvider应该被提升到单个实例化中,就像放在任何build()方法之外的全局变量中一样。这当然会缓存结果,因此您可以通过让值依赖于正在监视的其他提供程序()或通过FutureProvider.family将其设置为重新生成。在您的情况下,您应该使用消费者
,即
FutureProvider。。。,
儿童:消费者在您的情况下,您应该使用消费者
,即
FutureProvider。。。,
子:消费者您可以复制粘贴运行下面的完整代码
对这是正常的
第一次执行Build
报告列表
为null
并显示CircularProgressIndicator()
第二次执行构建
报告列表
有数据并显示数据
如果设置了listen:false
,final reportList=Provider.of(上下文,listen:false)代码>
您只会得到一个executebuild
,屏幕将始终显示circularproressindicator()
在工作演示中,模拟5秒的网络延迟,这样您就可以看到循环ProgressIndicator()
,然后显示列表视图
您可以参考
代码片段
Widget build(BuildContext context) {
print("Execute Build");
final reportList = Provider.of<List<ReportModel>>(context);
print("reportList ${reportList.toString()}");
if (reportList == null) {
print("reportList is null");
return Center(child: CircularProgressIndicator());
} else if (reportList.isEmpty) {
return Center(child: Text("Empty"));
}
return Scaffold(
body: ListView.builder(
itemCount: reportList.length,
小部件构建(构建上下文){
打印(“执行构建”);
最终报告列表=提供者(上下文);
打印(“reportList${reportList.toString()}”);
if(reportList==null){
打印(“报告列表为空”);
返回中心(子项:CircularProgressIndicator());
}else if(reportList.isEmpty){
返回中心(子项:文本(“空”);
}
返回脚手架(
正文:ListView.builder(
itemCount:reportList.length,
工作演示
完整代码
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ReportModel {
String title;
ReportModel({this.title});
}
class ReportsProvider with ChangeNotifier {
Future<List<ReportModel>> loadReportData(int no) async {
await Future.delayed(Duration(seconds: 5), () {});
return Future.value([
ReportModel(title: "1"),
ReportModel(title: "2"),
ReportModel(title: "3")
]);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ReportsPage(),
);
}
}
class ReportsPage extends StatelessWidget {
const ReportsPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FutureProvider<List<ReportModel>>(
create: (_) async => ReportsProvider().loadReportData(1),
initialData: null,
catchError: (_, __) => null,
child: const ReportWidg());
}
}
class ReportWidg extends StatelessWidget {
const ReportWidg();
@override
Widget build(BuildContext context) {
print("Execute Build");
final reportList = Provider.of<List<ReportModel>>(context);
print("reportList ${reportList.toString()}");
if (reportList == null) {
print("reportList is null");
return Center(child: CircularProgressIndicator());
} else if (reportList.isEmpty) {
return Center(child: Text("Empty"));
}
return Scaffold(
body: ListView.builder(
itemCount: reportList.length,
itemBuilder: (context, index) {
return Card(
elevation: 6.0,
child: Padding(
padding: const EdgeInsets.only(
top: 6.0, bottom: 6.0, left: 8.0, right: 8.0),
child: Text(reportList[index].title.toString()),
));
}),
);
}
}
导入“包装:颤振/材料.省道”;
导入“包:provider/provider.dart”;
类报告模型{
字符串标题;
ReportModel({this.title});
}
带有ChangeNotifier的类ReportsProvider{
未来loadReportData(int no)异步{
等待未来。延迟(持续时间(秒:5),({});
返回未来值([
报告模型(标题:“1”),
报告模型(标题:“2”),
报告模型(标题:“3”)
]);
}
}
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
),
主页:ReportsPage(),
);
}
}
类ReportsPage扩展了无状态小部件{
const ReportsPage({Key}):super(Key:Key);
@凌驾
小部件构建(构建上下文){
返回未来提供者(
创建:(41; async=>ReportsProvider().loadReportData(1),
initialData:null,
catchError:(u,u)=>null,
child:const ReportWidg());
}
}
类ReportWidg扩展了无状态小部件{
const ReportWidg();