Flutter Stack组件中Visibility状态不更新,点击下载分享不显示加载指示器
问题原因
- 首先是
Stack组件的子元素顺序错误:你把CircularProgressIndicator放在了第一个子节点,后面紧跟的是背景色为白色的WebView容器,容器完全覆盖了下层的加载控件,所以就算isLoading变为true,加载控件也会被上层的白色容器挡住,用户看不到。 - 下载分支的状态更新漏加
setState:download2方法中,普通下载完成后的isLoading = false是直接赋值,没有包裹setState,会导致下载完成后加载控件无法正常隐藏。 - 异常场景无状态重置:权限请求、下载过程中如果抛出异常,没有对应的
isLoading = false逻辑,可能会导致加载框一直显示。 - 存在冗余的嵌套
setState调用:_onItemTapped方法外层已经包裹了setState,case2、case3内部不需要再重复套一层setState,虽然不影响功能但属于冗余代码。
修复方案
- 调整
Stack的子元素顺序,把WebView容器放在前面,加载控件放在最后,保证加载控件浮在最上层:
body: Stack( children: <Widget>[ // WebView容器放前面 Align( alignment: Alignment.center, child: Container( color: Colors.white, height: MediaQuery.of(context).size.height / 1.5, child: WebviewScaffold( url: weburl, displayZoomControls: true, withJavascript: true, scrollBar: true, withZoom: true, hidden: true, ), ), ), // 加载控件放最后,浮在最上层 Align( alignment: Alignment.center, child: Visibility( visible: isLoading, child: CircularProgressIndicator()), ), ], ),
- 修正下载分支的状态更新,给普通下载完成的
isLoading赋值包裹setState:
} else { setState(() { isLoading = false; }); Fluttertoast.showToast( msg: type + "Downloaded in " + fullPath, toastLength: Toast.LENGTH_SHORT, timeInSecForIosWeb: 1, backgroundColor: Colors.white, textColor: Colors.black, fontSize: 16.0); }
- 在所有异常捕获分支添加状态重置逻辑,避免加载框一直显示:
// 示例:getPermission方法的catch分支 catch (e) { print(e); setState(() { isLoading = false; }); } // download2、shareFile方法的catch分支也同理添加isLoading重置逻辑
- 去掉冗余的嵌套
setState,优化_onItemTapped逻辑:
void _onItemTapped(int index) { setState(() { switch (index) { case 0: break; case 1: _makingPhoneCall(); break; case 2: isLoading = true; getPermission('download'); break; case 3: isLoading = true; getPermission('share'); break; } }); }
内容的提问来源于stack exchange,提问作者Vishali
相关产品推荐
相关产品推荐

