即使在StreamBuilder
示例中,每个关于StatelessWidget
的示例都以flutter
开头,但是如何在StatelessWidget
小部件中取消订阅?例如,我正在经历firestore
example。
class MessageList extends StatelessWidget {
MessageList({this.firestore});
final Firestore firestore;
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: firestore.collection('messages').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) return const Text('Loading...');
final int messageCount = snapshot.data.documents.length;
return ListView.builder(
itemCount: messageCount,
itemBuilder: (_, int index) {
final DocumentSnapshot document = snapshot.data.documents[index];
return ListTile(
title: Text(document['message'] ?? '<No message retrieved>'),
subtitle: Text('Message ${index + 1} of $messageCount'),
);
},
);
},
);
}
}
现在如何取消收听firestore.collection('messages').snapshots()
流?
我在应用中使用实时数据库,这就是我的操作方式
class MessgaeView extends StatefulWidget {
final String _chatId;
MessgaeView(this._chatId);
@override
_MessgaeViewState createState() => _MessgaeViewState();
}
class _MessgaeViewState extends State<MessgaeView> {
Stream<Event> _messageStream;
@override
void initState() {
_messageStream = _database
.reference()
.child("message/${widget._chatId}")
.limitToLast(1)
.onChildAdded;
super.initState();
}
@override
void dispose() {
_messageStream.drain();
super.dispose();
}
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _messageStream,
builder: (context, snapshot) {
if (!snapshot.hasData) return CupertinoActivityIndicator();
final message =
(snapshot.data.snapshot as DataSnapshot).value['message'];
return Text(message);
});
}
}
答案 0 :(得分:2)
只需用null
替换以前的流实例。
这将需要类似于以下内容的代码:
setState(() {
_messageStream = null;
});
这样做将停止收听流。但是StreamBuilder
仍将保留以前的值。
答案 1 :(得分:0)
我遇到了同样的问题,并通过 StreamSubscription
解决了例如,将 StreamSubscription 定义为全局
StreamSubscription<Event> _counterSubscription;
然后在您要收听数据的地方像这样注册您的订阅
_counterSubscription = _counterRef.onValue.listen((Event event) {
setState(() {
_counter = event.snapshot.value ?? 0;
});
});
,当您想删除监听器时,只需编写以下代码
if(_counterSubscription !=null)
_counterSubscription .cancel();