Flutter应用短暂红屏:Widget Library捕获NoSuchMethodError问题
Hey,我一眼就看出问题出在哪了——你的_current变量是在异步的_init方法里初始化的,但Flutter第一次渲染AudioButton的时候,_init还没执行完成,这时候_current还是个null,你直接去调用_current.duration可不就触发空指针异常了嘛!这就是启动时短暂红屏的原因。
下面给你两种简单有效的解决办法:
方法一:空安全检查(快速修复)
直接在访问_current的属性时加上空安全判断,避免null访问。修改build方法里的时长显示文本:
原来的代码:
Text( "${_current.duration.inSeconds.toString()}", style: TextStyle(fontSize: 60.0), ),
改成:
Text( "${_current?.duration?.inSeconds ?? 0}", style: TextStyle(fontSize: 60.0), ),
这里用到了两个Dart空安全特性:
?.:如果左侧对象是null,就不会继续调用后面的属性,直接返回null??:如果前面的值是null,就使用后面的默认值(这里是0)
这样即使_current还没初始化,也不会报错,而是显示0,等_init完成后会自动更新为正确的时长。
方法二:用FutureBuilder等待初始化完成(更优雅)
如果想在初始化完成前给用户显示加载状态,或者有多个异步操作需要等待,推荐用FutureBuilder:
- 先在
AudioButtonState类里添加一个Future变量,用来保存_init方法的异步结果:
class AudioButtonState extends State<AudioButton> { // ... 其他变量 Future<void> _initFuture; // 新增这个变量 @override void initState() { super.initState(); _initFuture = _init(); // 把异步方法的Future存起来 } // ... 其他方法 }
- 修改
build方法,用FutureBuilder包裹整个UI:
@override Widget build(BuildContext context) { return FutureBuilder( future: _initFuture, builder: (context, snapshot) { // 如果初始化还在进行中,显示加载指示器 if (snapshot.connectionState != ConnectionState.done) { return Center(child: CircularProgressIndicator()); } // 初始化完成后,渲染原来的UI return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ // 你的三个RaisedButton ], ), SizedBox(height: 20.0), Text( "${_current.duration.inSeconds.toString()}", style: TextStyle(fontSize: 60.0), ), SizedBox(height: 50.0), Text("Status : $_currentStatus"), ], ); }, ); }
这样在_init执行完成前,用户会看到一个加载转圈的指示器,不会出现红屏,初始化完成后再显示完整的AudioButton界面。
你可以根据自己的需求选其中一种方法,两种都能解决你遇到的问题。
内容的提问来源于stack exchange,提问作者user3788874
相关产品推荐
相关产品推荐

