Flutter 如何在Stateful有状态组件之间调用函数并同步状态
状态同步实现方案
现有代码的核心问题:
- 每次调用
toggleRecording时都会重新实例化SoundStream对象,旧实例的录制状态、资源会直接丢失,无法复用状态 - 两个类各自维护独立的
_isRecording变量,没有建立同步联动,两个独立状态源必然会出现不一致 - Recorder类的
toggleRecording方法没有将最终操作后的状态回传给HomeScreen,也没有处理异步操作的状态同步
步骤1:复用Recorder实例,禁止每次toggle重新创建
在HomeScreen的initState生命周期中完成Recorder初始化,全程复用同一个实例:
// HomeScreen 类内代码 late SoundStream recorder; bool _isRecording = false; @override void initState() { super.initState(); // 仅初始化一次recorder实例 recorder = SoundStream(isRecording: _isRecording); }
步骤2:修改HomeScreen的toggleRecording逻辑
不要自行修改本地_isRecording,改为调用recorder的toggle方法后,以recorder返回的实际运行状态为准更新本地状态:
void toggleRecording() async { // 调用recorder的toggle方法,拿到最终的录制状态 bool currentRecordingState = await recorder.toggleRecording(); // 以recorder返回的状态为唯一标准更新本地状态 setState(() { _isRecording = currentRecordingState; }); if (_isRecording) { startTimer(); _stopwatch.start(); } else { stopTimer(); _stopwatch.stop(); } }
步骤3:修改Recorder类的toggleRecording方法,返回最终状态
将toggle方法改为异步返回操作后的实际录制状态,同时维护类内_isRecording与实际运行状态同步:
// 方法改为返回Future<bool>,返回最终的录制状态 Future<bool> toggleRecording() async { bool newState; if (widget.isRecording) { await _recorder.stop(); await save(_micChunks, 44100); newState = false; } else { await _recorder.start(); newState = true; } // 更新类内的_isRecording状态 _isRecording = newState; return newState; }
可选优化
如果需要支持外部直接修改录制状态触发联动,可以给Recorder类添加状态更新的回调参数,在状态变化时主动通知上层:
// SoundStream类的构造函数添加回调 final Function(bool isRecording) onRecordingStateChanged; SoundStream({required this.isRecording, required this.onRecordingStateChanged}); // 状态更新后调用回调通知上层 _isRecording = newState; widget.onRecordingStateChanged(_isRecording);
HomeScreen初始化recorder时传入回调,收到回调直接更新本地_isRecording即可,适合状态需要多处修改的场景。
内容的提问来源于stack exchange,提问作者who-aditya-nawandar
相关产品推荐
相关产品推荐

