flutter - 如何避免streambuilder执行不必要的时间
问题描述
我正在尝试显示有效的文档列表,但我读到一个好的做法是管理状态(我目前也在尝试理解)。在这种情况下,每次我使用 bottomNavigationBar 更改屏幕时,streamBuilder 都会执行(我总是看到 CircularProgressIndicator)。我尝试在 intState 中调用集合引用,但仍然是同样的问题,我的代码:
class Deparments extends StatefulWidget {
Deparments({Key? key, required this.auth}) : super(key: key);
final AuthBase auth;
@override
_DeparmentsState createState() => _DeparmentsState();
}
class _DeparmentsState extends State<Deparments> {
late final Stream<QuerySnapshot<Object?>> _widget;
Stream<QuerySnapshot<Object?>> getProds(){
CollectionReference ref = FirebaseFirestore.instance.collection("Departamentos");
return ref.snapshots();
}
@override
void initState() {
super.initState();
_widget = getProds();
}
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: SideMenu(auth: widget.auth),
appBar: AppBar(
title: Text("Departamentos"),
centerTitle: true,
backgroundColor: Colors.green,
),
body: Container(
child: StreamBuilder<QuerySnapshot> (
stream: _widget,
builder: (BuildContext context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
List deparments =
snapshot.data!.docs.map((doc) => doc.id).toList();
return Column(
children: [
Expanded(
child: ListView.builder(
padding: EdgeInsets.only(top: 10),
scrollDirection: Axis.vertical,
itemCount: deparments.length,
itemBuilder: (context, index) {
return SingleChildScrollView(
child: Card(
child: Text(deparments[index]),
),
);
}),
)
],
);
}
}),
),
);
}
}
更新:对于那些面临同样问题的人,Tayan 提供了一个有用的解决方案,他有一个显示解决方案的视频https://stackoverflow.com/a/64057210/9429407
解决方案
初始化状态不会帮助您避免重建,因为在更改选项卡时 Flutter 会重建您的屏幕。所以我们需要一些方法来让我们的屏幕保持活跃,所以这里出现了 AutomaticKeepAliveClientMixin。
class _HomeState extends State<Home> with AutomaticKeepAliveClientMixin<Home> {
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
//Make sure to include the below method
super.build(context);
return SomeWidget();
}
}
上述实现使您的所有选项卡状态保持不变,并且不会再次重建选项卡。好吧,这可能会达到您的目的,但它可能不会空闲,因为即使用户实际上没有访问过标签,这也会一次加载所有标签,因此要避免构建,除非单击标签,请结合综合浏览量使用上述方法。
此外,如果您想要一种更好的方法来管理状态并将一些读取调用保存到 Firestore,那么您应该在本地存储数据并仅获取那些需要的数据和/或使用分页。
推荐阅读
- swift - xcschememanagement.plist 文件在 XCode 中的作用是什么?我可以用 git 忽略它吗?
- linux - 当我有多个打开时关闭单个 vim 实例
- android - 使用 React Native 在地图上生成“视野外”标记指示器
- entity-framework - 带有导航属性的存储库插入抛出“外键约束失败”
- python - SWIG Python 从父对象转换为子对象
- gcloud - gcloud 会使用我的 SSH 密钥登录还是我总是需要通过网络登录?
- performance - 在python中绘制圆圈并保存为png的最快方法是什么?
- node.js - 在同一个 Kubernetes 节点上多次复制 Node.js Kubernetes 服务器 pod 是否有意义?
- oracle - 如何使用游标更新表
- google-cloud-platform - 如何将 Google Big Query 输出提供给客户端网络