【发布时间】:2021-02-22 19:04:02
【问题描述】:
我有一个显示项目列表的页面。通过单击上一页的按钮可以到达此页面。检索完成后,我使用 FutureBuilder 填充项目列表。当 ConnectionState 处于“等待”状态时,我会显示一个圆形进度指示器。但是,在 FutureBuilder 完成之前,进度指示器永远不会出现,并且列表页面不会出现推送。如果我在“if (snapshot.connectionState == ConnectionState.waiting)”块中放置一个断点,它会命中该断点,但屏幕在返回时不会改变。屏幕确实按预期显示,但随着项目列表的增加,屏幕出现的时间越来越长。我在这里错过了什么吗:
class MyListScreen extends StatelessWidget {
RelevantObject relevantObject;
MyListScreen(this.relevantObject, {Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
final bloc = MyListBloc(relevantObject);
return FutureBuilder<Widget>(
future: _buildList(bloc, context),
builder: (BuildContext context, AsyncSnapshot<Widget> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Scaffold(
appBar: AppBar(
centerTitle: false,
title: Text(
"My Title",
),
),
body: Center(child: CircularProgressIndicator()),
);
} else {
return BlocProvider<MyListBloc>(
bloc: bloc, child: snapshot.data);
}
},
);
}
Future<Widget> _buildList(
MyListBloc bloc, BuildContext myContext) async {
//await bloc.init();
List<Widget> listView = await bloc.getListItems(myContext);
return StreamBuilder<List<MyListItem>>(
stream: bloc.drawingCanvasListStream,
builder: (context, snapshot) {
return Scaffold(
appBar: AppBar(
title: Text('My Title'),
centerTitle: false,
),
body: SingleChildScrollView(
child: Column(mainAxisSize: MainAxisSize.min, children: listView),
),
);
});
}
}
更新:
我改变了我的方法,并试图让它更简单一些。这是我更新的“列表屏幕”。
class MyListScreen extends StatefulWidget{
final bloc = MyListBloc();
@override
_MyListState createState() => _MyListState();
}
class _MyListState extends State<MyListScreen>{
@override
void initState() {
widget.bloc.getListItems(context);
super.initState();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return StreamBuilder<List<Widget>>(
stream: widget.bloc.myListStream,
builder: (context, snapshot) {
return Scaffold(
appBar: AppBar(
title: Text('My App'),
centerTitle: false,
),
body:
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min, children: snapshot.data == null ? [Center(child: CircularProgressIndicator())] :
snapshot.data
)
,
),
);
});
}
}
MyListBloc 类有一个 List
更新 2:
我也试过了,没用:
import 'package:flutter/material.dart';
class MyListScreen extends StatefulWidget{
final bloc = MyListBloc();
@override
_MyListState createState() => _MyListState();
}
class _MyListState extends State<MyListScreen>{
@override
void initState() {
widget.bloc.getListItems(context);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My App'),
centerTitle: false,
),
body: StreamBuilder<List<Widget>>(
stream: widget.bloc.myListStream,
builder: (context, snapshot) {
if(snapshot.connectionState == ConnectionState.waiting){
return Center(child: CircularProgressIndicator());
}
else {
return SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min, children: snapshot.data
)
,
);
}
})
);
}
}
widget.bloc.getListItems(context) 是我不等待的异步方法。然而,屏幕仍然没有出现,直到 snapshot.data != null。
【问题讨论】:
-
可能是因为它无法区分 2 个脚手架。在上面放一个 ValueKey,看看是否有帮助。理想情况下,您不会在未来构建小部件。只需拥有
bloc.drawingCanvasListStream或FutureBuilder的未来并在构建器中渲染所有小部件
标签: flutter dart asynchronous flutter-futurebuilder