flutter 自定义加载中间页
- 前言
- LoadingStateWidget 封装思路
- 总结
前言
在日常移动开发中,很多时候需要我们添加一个加载中间页,即加载中,加载失败,加载重试,加载完成等功能,这样可以避免在无网或者弱网情况下,导致无法加载完整UI界面,这样的影响是非常不好的。
本篇文章将记录如果封装一个统一的加载中间页。
LoadingStateWidget 封装思路
在文章开始之前,我们先来写一个枚举,用来定义三个加载状态,即加载中,加载成功,加载失败
enum ViewState { loading, done, error }
新建一个 LoadingStateWidget 继承自StatelessWidget ,根据我们的需要的大致需求,我们需要接收一个child,一个当前加载状态,一个返回参数,即加载失败,重新加载的retry 方法。
final ViewState viewState;
final VoidCallback retry;
final Widget child;
接下来就是业务代码
- loading: 加载中需要展示的界面
- error: 加载失败需要展示的界面
- done:加载成功直接返回child
我这里加载中,直接使用了系统的转圈组件CircularProgressIndicator,当然,这个组件是可以自定义的哦
// 加载中
Widget get _loadingView {
return const Center(
child: CircularProgressIndicator(),
);
}
加载失败的时候需要展示的界面,在这里,一般都会加一个重试的按钮,具体的功能,可以根据需求去绘制界面功能
// 加载失败
Widget get _errorView {
return Center(
child: Column()
);
}
完整代码如下:
enum ViewState { loading, done, error }
class LoadingStateWidget extends StatelessWidget {
final ViewState viewState;
final VoidCallback retry;
final Widget child;
const LoadingStateWidget(
{Key? key,
this.viewState = ViewState.loading,
required this.retry,
required this.child})
: super(key: key);
Widget build(BuildContext context) {
if (viewState == ViewState.loading) {
return _loadingView;
}
if (viewState == ViewState.error) {
return _errorView;
} else {
return child;
}
}
// 加载中
Widget get _loadingView {
return const Center(
child: CircularProgressIndicator(),
);
}
// 加载失败
Widget get _errorView {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/images/ic_error.png",
width: 100,
height: 100,
),
const Padding(
padding: EdgeInsets.only(top: 8),
child: Text(
TigerString.net_request_fail,
style: TextStyle(
fontSize: 18,
color: Colors.red,
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 8,
),
child: OutlinedButton(
onPressed: retry,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.white),
overlayColor: MaterialStateProperty.all(Colors.black12),
),
child: const Text(
TigerString.reload_again,
style: TextStyle(
color: Colors.black87,
),
),
),
),
],
),
);
}
}
使用方法如下:
传入三个参数,加载的延时任务,当前加载状态,及加载完成后需要展示的child
LoadingStateWidget(
retry: model.getData,
viewState: model.viewState,
child: HomePageWidget.bodyWidget(model),
)
我这里的加载refresh 方法,直接使用的是一个延时加载的模拟方式
getData() async {
if(viewState == ViewState.error){
viewState = ViewState.loading;
notifyListeners();
}
await Future.delayed(Duration(seconds: 5));
viewState = ViewState.error;
notifyListeners();
}
总体内容比较简单,代码量也没有多少,个人觉得没什么值得浪费大量语言来描述,看一下运行结果:
总结
记得之前看到一个大佬说过这么一句话,在flutter 中,只有你使用的widget 够多,就没有完成不了的界面,请问你是怎么看待这句话呢?评论区告诉我哦!!!