Flutter中如何为Stream Builder的每条新数据触发通知或控制台打印?
问题描述
在Flutter应用中,我使用Stream Builder获取API数据,期望每次Stream返回新条目时,能够触发通知或在控制台打印消息。我了解有通知相关的第三方包,但不清楚应该在何处编写触发新条目通知的函数。
以下是我的代码:
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; void main() async { runApp(MaterialApp(home: PeriodicRequester(),)); } class PeriodicRequester extends StatelessWidget { Stream<http.Response> getRandomNumberFact() async* { yield* Stream.periodic(Duration(seconds: 5), (_) { return http.get(Uri.parse("https://script.google.com/macros/s/AKfycbwhbpF4ZxuMUcTZZvObAqvE1pAbEfPt7gZHRV1vVp8PuKt39-ouOm-kQJ1U1LtlEwV-/exec")); }).asyncMap((event) async => await event); } @override Widget build(BuildContext context) { return StreamBuilder<http.Response>( stream: getRandomNumberFact(), builder: (context, snapshot) => snapshot.hasData ? Center(child: Text(snapshot.data!.body)) : CircularProgressIndicator(), ); } }
解决方案
有几个合适的位置可以添加触发通知/打印的逻辑,具体实现如下:
1. 在Stream的asyncMap环节处理
直接在数据流处理阶段加入逻辑,每次获取到API响应时执行:
Stream<http.Response> getRandomNumberFact() async* { yield* Stream.periodic(Duration(seconds: 5), (_) { return http.get(Uri.parse("https://script.google.com/macros/s/AKfycbwhbpF4ZxuMUcTZZvObAqvE1pAbEfPt7gZHRV1vVp8PuKt39-ouOm-kQJ1U1LtlEwV-/exec")); }).asyncMap((event) async { final response = await event; // 控制台打印新数据 print("新数据到达:${response.body}"); // 此处调用通知触发逻辑,比如第三方通知包的方法 // showNotification(response.body); return response; }); }
2. 在StreamBuilder的builder回调中处理
当StreamBuilder接收到新数据时,同步执行通知/打印逻辑:
@override Widget build(BuildContext context) { return StreamBuilder<http.Response>( stream: getRandomNumberFact(), builder: (context, snapshot) { // 仅在数据更新且连接活跃时触发 if (snapshot.hasData && snapshot.connectionState == ConnectionState.active) { print("新数据更新:${snapshot.data!.body}"); // 触发通知 // showNotification(snapshot.data!.body); } return snapshot.hasData ? Center(child: Text(snapshot.data!.body)) : CircularProgressIndicator(); }, ); }
3. 用StreamTransformer封装逻辑
如果逻辑复杂,可封装为独立的Transformer,保持代码模块化:
// 自定义StreamTransformer final notifyTransformer = StreamTransformer<http.Response, http.Response>.fromHandlers( handleData: (data, sink) { print("新条目触发:${data.body}"); // 触发通知 // showNotification(data.body); sink.add(data); }, ); // 在Stream中应用Transformer Stream<http.Response> getRandomNumberFact() async* { yield* Stream.periodic(Duration(seconds: 5), (_) { return http.get(Uri.parse("https://script.google.com/macros/s/AKfycbwhbpF4ZxuMUcTZZvObAqvE1pAbEfPt7gZHRV1vVp8PuKt39-ouOm-kQJ1U1LtlEwV-/exec")); }).asyncMap((event) async => await event) .transform(notifyTransformer); }
第三方通知包使用说明
如果使用flutter_local_notifications这类通知包,只需将上述代码中注释的showNotification部分替换为对应包的通知触发代码即可。例如初始化通知插件后,在对应位置调用插件的show方法展示通知。
内容的提问来源于stack exchange,提问作者MOBILES RECOVERY
相关产品推荐
相关产品推荐

