Flutter监听BLE ESP32数据时!_debugLocked报错及跳转布局异常问题
问题1:!_debugLocked报错解决
原因:StreamBuilder的builder方法属于Widget渲染流程的一部分,在渲染未完成时直接调用Navigator跳转,触发了框架的防重复渲染校验。
修改方案:
- 在
_ConfDeviceSetState中新增布尔变量bool _hasNavigated = false;防止重复跳转 - 把跳转逻辑包裹在
WidgetsBinding.instance.addPostFrameCallback中,等当前帧渲染完成后再执行跳转
修改后的StreamBuilder部分代码:
// 先在State类里新增变量 bool _hasNavigated = false; // 原来的StreamBuilder外层先加isReady判断,stream初始化完成后再渲染 if (!isReady) { return const SizedBox.shrink(); } return StreamBuilder<List<int>>( stream: stream, initialData: lastValue, builder: (BuildContext context, AsyncSnapshot<List<int>> snapshot) { if (!snapshot.hasData || _hasNavigated) { return const SizedBox.shrink(); } var currentValue = _dataParser(snapshot.data); if (currentValue == 1) { _hasNavigated = true; WidgetsBinding.instance.addPostFrameCallback((_) { Navigator.push( context, MaterialPageRoute( builder: (context) { return ConfDeviceDone( device: widget.device, ); }, ), ); }); } return const SizedBox.shrink(); }, );
问题2:页面底部溢出解决
原因:Column的子组件总高度超过了屏幕可视高度,触发溢出提示。
修改方案:给Scaffold的body的Column外层包裹SingleChildScrollView,让页面可以滚动:
body: SingleChildScrollView( child: Column( // 原有Column内容保持不变 ), )
问题3:“Bluetooth is not active”误报解决
原因:stream还没完成初始化(isReady为false)时,StreamBuilder就传入了空的stream对象,触发flutter_blue的内部错误提示。问题1中添加的isReady判断已经覆盖该场景,仅在BLE服务、特征值发现完成且stream初始化成功后才渲染StreamBuilder,即可解决误报问题。
问题4:完成页无法自动跳转首页解决
原因:跳转执行时页面可能已经被销毁,上下文无效导致跳转逻辑不执行,添加mounted判断即可。
修改后的ConfDeviceDone的initState代码:
@override void initState() { super.initState(); const d = Duration(seconds: 2); Future.delayed(d, () { // 加mounted判断,确保页面还在栈中才执行跳转 if (mounted) { Navigator.pushAndRemoveUntil( context, MaterialPageRoute( builder: (context) { return Homepage(device: widget.device); }, ), (route) => false, ); } }); }
内容的提问来源于stack exchange,提问作者Nabia Salman
相关产品推荐
相关产品推荐

