Flutter中如何在StreamBuilder场景下更新监听的Stream流?
解决方案
先修复现有代码的基础缺陷
你现有代码存在几个语法&逻辑问题,会直接导致方法不执行:
- 抽象类
BaseState要求processState、nextState返回Future,但你在FSM_State1、FSM_State2的实现里把返回值写成了void,会导致异步逻辑完全不可控 FSM_State2的nextState方法没有按照接口要求接收FSM_Manager入参- State类不要自定义构造方法接收参数,直接通过
widget.xxx读取上层传入的参数即可 - StreamBuilder的stream参数写错了,
_stateContext.outState应该改为_fsmManager.outState - 缺少流销毁逻辑,会引发内存泄漏
明确FSM执行时序
正确的执行顺序应该是:
- FSM初始化时设置初始状态,同步将初始状态推入流
- 每次流接收到新状态时,先执行当前状态的
processState方法完成识别逻辑 - 识别完成后调用
nextState方法触发状态切换,FSM内部调用setState将新状态推入流,自动进入下一轮循环 - StreamBuilder监听流变更自动重绘UI
正确的调用位置
在initState中监听状态流,自动触发状态处理&切换即可,不需要在build、didUpdateWidget中调用:
// 先给FSM_Manager补充销毁方法 class FSM_Manager{ // ...原有代码 void dispose() { _stateStream.close(); } } // 修改Widget的State实现 class _RecognitionScreenState extends State<RecognitionScreen> { late FSM_Manager _fsmManager; late ItemToRecognize item; @override void initState() { super.initState(); _fsmManager = widget.fsmManager; item = widget.item; // 初始化FSM初始状态 _fsmManager.setState(FSM_State1()); // 监听状态流,每次状态变更自动执行处理逻辑 _fsmManager.outState.listen((newState) async { await _fsmManager.processState(item); await _fsmManager.nextState(); }); } @override void dispose() { _fsmManager.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return StreamBuilder<RecognitionState>( stream: _fsmManager.outState, builder: (context, snapshot) { if (snapshot.hasData) { return Text(snapshot.data!.stateID.toString()); } return const Text(''); }); } }
如果你需要手动触发识别(比如用户点击按钮后才开始处理),只需要把processState和nextState的调用放到交互事件回调里即可:
ElevatedButton( onPressed: () async { await _fsmManager.processState(item); await _fsmManager.nextState(); }, child: const Text('开始识别') )
内容的提问来源于stack exchange,提问作者neonx97
相关产品推荐
相关产品推荐

