前言
之前框架使用的是方式有两种:
1、在根布局中使用stack 如下:
return Stack(
children:[
(...),
loadingWidget(),
]
);
通过visible或者offstage进行包裹,并控制显示。
2、使用showDialog
showDialog(
builder:(ctx)=>loadingWidget();
)
方案1 图层多了一层,展示效果不灵活。
方案2 开关不好控制。
之后决定再尝试一下方案3,具体实现如下:
实现
LoadingProgress
增加一个LoadingProgress页面
class LoadingProgress extends StatefulWidget{
final Widget progress;
final Color bgColor;
final DialogLoadingController controller;
const LoadingProgress({Key key, this.progress,
this.bgColor,@required this.controller })
: super(key: key);
@override
State<StatefulWidget> createState() {
return LoadingProgressState();
}
}
class LoadingProgressState extends BaseState<LoadingProgress> {
@override
void initState() {
super.initState();
//对controller进行监听
widget.controller.addListener(() {
if(widget.controller.isShow){
//todo
}else{
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
Navigator.of(context).pop();
});
}
});
}
@override
void dispose() {
widget.controller.isShow = false;
widget.controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Container(
color: widget.bgColor??Color.fromRGBO(34, 34, 34, 0.3),
width: size.width,height: size.height,
alignment: Alignment.center,
child:widget.progress?? DoubleCircleLoadingWidget(),
);
}
}
很简单的代码
DialogLoadingController
之后我们增加一个controller用于控制loading的显隐,这样后续还可以拓展其他功能
class DialogLoadingController extends ChangeNotifier{
bool isShow = true;
dismissDialog(){
isShow = false;
notifyListeners();
}
}
ok,功能完成了,下面加到baseState里(我们自己对state的封装)。
加入功能
DialogLoadingController _dialogLoadingController;
showProgressDialog({Widget progress,
Color bgColor,}){
if(_dialogLoadingController == null){
_dialogLoadingController = DialogLoadingController();
Navigator.of(context).push(PageRouteBuilder(
opaque: false,
pageBuilder: (ctx,animation,secondAnimation){
return LoadingProgress(controller: _dialogLoadingController,
progress: progress,bgColor: bgColor,);
}
));
}
}
dismissProgressDialog(){
_dialogLoadingController?.dismissDialog();
_dialogLoadingController = null;
}
这样,我们在当前页面就可以随时随地的调用
showProgressDialog()
dismissProgressDialog()
进行全屏的loading弹窗显示了。
谢谢大家阅读,有不足的地方欢迎大家指出,如果有更好的实现方式也请告诉我。 :)
Bedrock 框架
目前该功能已加入框架内。