官方没有提供加载中的组件, 我们可以自己封装一个:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
// ignore: must_be_immutable
class NetLoadingDialog extends StatefulWidget {
String loadingText;
bool outsideDismiss; // 是否可以点击消失, 默认false
Function dismissCallback; // 消失后的回调
Future<dynamic> requestCallBack; // 请求回调, 一定要传, 否则loading不会消失
NetLoadingDialog(
{Key key,
this.loadingText = "loading...",
this.outsideDismiss = false,
this.dismissCallback,
this.requestCallBack})
: super(key: key);
@override
State<NetLoadingDialog> createState() => _LoadingDialog();
}
class _LoadingDialog extends State<NetLoadingDialog> {
_dismissDialog() {
if (widget.dismissCallback != null) {
widget.dismissCallback();
}
// 隐藏Loading
Navigator.of(context).pop();
}
@override
void initState() {
super.initState();
if (widget.requestCallBack != null) {
widget.requestCallBack.then((_) {
// 请求成功后隐藏Loading
Navigator.pop(context);
}).catchError((err) {
// 请求失败后隐藏Loading
Navigator.pop(context);
// 吐司提示错误原因
Fluttertoast.showToast(
msg: "请求失败: $err",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIos: 1,
backgroundColor: Colors.grey,
textColor: Colors.white,
fontSize: 16.0
);
});
}
}
@override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: widget.outsideDismiss ? _dismissDialog : null, // 是否可以通过点击让loading消失
child: Material(
type: MaterialType.transparency,
child: new Center(
child: new SizedBox(
width: 120.0,
height: 120.0,
child: new Container(
decoration: ShapeDecoration(
color: Color(0xffffffff),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
),
),
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new CircularProgressIndicator(), // 加载动画
new Padding(
padding: const EdgeInsets.only(
top: 20.0,
),
child: new Text(
widget.loadingText,
style: new TextStyle(fontSize: 12.0),
),
),
],
),
),
),
),
),
);
}
}
使用方式:
// 重点就是实现返回Future的方法, 无论成功与否, 都要返回Future, 否则loading不会消失
Future<dynamic> _register() {
Future<dynamic> future = HttpUtil().resolve(Api.code);
future.then((res) {
print('成功啦');
}).catchError((err) {
print('失败啦');
});
return future;
}
// 通过showDialog调用显示Loading
showDialog(
context: context,
barrierDismissible: false,
builder: (_) {
return new NetLoadingDialog(
loadingText: '加载中...',
requestCallBack: _register(), // 传入一个返回Future的方法
);
});
当然, loading图不一定要使用 CircularProgressIndicator
, 也可以使用第三方库, 有一些很不错的库: