Flutter StreamBuilder 在加载时删除旧数据
Flutter StreamBuilder removes old data while loading
目前,我有一个 StreamBuilder 从 Firebase 中为群发消息应用提取数据。我有一个 snapshot.hasData 检查以确保在显示消息之前有数据。问题是,当 setState 重建小部件时,它还会重建 StreamBuilder,导致它在再次完成加载数据之前显示静态 snapshot.hasData == false 内容。这看起来真的很糟糕,因为它的加载速度太快了,以至于每次重建时屏幕看起来都在闪烁一秒钟。
我该如何在数据自行重新加载时保留数据,使其看起来不会闪烁?
有什么方法可以阻止 StreamBuilder 在特定情况下重建?
谢谢!
编辑添加的当前代码。
var firebaseStream;
@override
void initState() {
super.initState();
firebaseStream = Firestore.instance
.collection('groups')
.document(groupID)
.collection('messages')
.orderBy('date', descending: true)
.limit(15)
.snapshots();
StreamBuilder(
stream: firebaseStream,
builder: (context, snapshot) {
if (!snapshot.hasData)
return Container(
color: Colors.red,);
return ListView.builder(
听起来好像您是直接在 StreamBuilder
流中获取数据 属性:
StreamBuilder(
stream: firebase.getData(),
...
)
这个问题是每次调用 setState
时都会创建一个新流,并且总是给出初始 null
值。相反,您应该使用 StatefulWidget
并在 initState
期间在您的状态中创建一个变量,以便它只运行一次。然后使用此变量作为 StreamBuilder
中的流 属性。这是一个非常简单的例子:
class Example extends StatefulWidget {
Example({Key key}) : super(key: key);
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
Stream firebaseData;
@override
void initState() {
super.initState();
firebaseData = Firebase.fetchData(); //Or whatever function you use
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: firebaseData,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data);
} else {
return Loading();
}
},
);
}
}
您尝试过使用 snapshot.Connection 状态吗?
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: firebaseData,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.active && snapshot.hasData) {
final data = snapshot.data;
return Text(data);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Loading(); // OR CircularProgressIndicator()
} else // Handle error here.
},
);
}
目前,我有一个 StreamBuilder 从 Firebase 中为群发消息应用提取数据。我有一个 snapshot.hasData 检查以确保在显示消息之前有数据。问题是,当 setState 重建小部件时,它还会重建 StreamBuilder,导致它在再次完成加载数据之前显示静态 snapshot.hasData == false 内容。这看起来真的很糟糕,因为它的加载速度太快了,以至于每次重建时屏幕看起来都在闪烁一秒钟。
我该如何在数据自行重新加载时保留数据,使其看起来不会闪烁?
有什么方法可以阻止 StreamBuilder 在特定情况下重建?
谢谢!
编辑添加的当前代码。
var firebaseStream;
@override
void initState() {
super.initState();
firebaseStream = Firestore.instance
.collection('groups')
.document(groupID)
.collection('messages')
.orderBy('date', descending: true)
.limit(15)
.snapshots();
StreamBuilder(
stream: firebaseStream,
builder: (context, snapshot) {
if (!snapshot.hasData)
return Container(
color: Colors.red,);
return ListView.builder(
听起来好像您是直接在 StreamBuilder
流中获取数据 属性:
StreamBuilder(
stream: firebase.getData(),
...
)
这个问题是每次调用 setState
时都会创建一个新流,并且总是给出初始 null
值。相反,您应该使用 StatefulWidget
并在 initState
期间在您的状态中创建一个变量,以便它只运行一次。然后使用此变量作为 StreamBuilder
中的流 属性。这是一个非常简单的例子:
class Example extends StatefulWidget {
Example({Key key}) : super(key: key);
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
Stream firebaseData;
@override
void initState() {
super.initState();
firebaseData = Firebase.fetchData(); //Or whatever function you use
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: firebaseData,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data);
} else {
return Loading();
}
},
);
}
}
您尝试过使用 snapshot.Connection 状态吗?
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: firebaseData,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.active && snapshot.hasData) {
final data = snapshot.data;
return Text(data);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Loading(); // OR CircularProgressIndicator()
} else // Handle error here.
},
);
}