为Flutter应用添加loading效果
在App中,如果一项任务需要长时间等待,我们通常会在页面上显示loading的状态,在Flutter中这可以通过使用 ProgressIndicator 小部件来完成。您可以通过编程方式显示进度 UI,方法是通过布尔型标志在控制呈现到进程 UI,并告诉 Flutter 在长时间运行任务开始之前更新其状态,并在结束之后隐藏它。
下面我们分别用两种方法展示Flutter中的loading效果。
1. 不用第三方的package
在下面的例子中,我们将构造函数分解为三个不同的函数。如果 showLoadingDialog() 是 true(当 widgets.length == 0)然后我们渲染 ProgressIndicator,否则我们在 ListView 中用数据显示。
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(new SampleApp());
}
class SampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Sample App',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new SampleAppPage(),
);
}
}
class SampleAppPage extends StatefulWidget {
SampleAppPage({Key key}) : super(key: key);
@override
_SampleAppPageState createState() => new _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
List widgets = [];
@override
void initState() {
super.initState();
loadData();
}
showLoadingDialog() {
return widgets.length == 0;
}
getBody() {
if (showLoadingDialog()) {
return getProgressDialog();
} else {
return getListView();
}
}
getProgressDialog() {
return new Center(child: new CircularProgressIndicator());
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Sample App"),
),
body: getBody());
}
ListView getListView() => new ListView.builder(
itemCount: widgets.length,
itemBuilder: (BuildContext context, int position) {
return getRow(position);
});
Widget getRow(int i) {
return new Padding(padding: new EdgeInsets.all(10.0),
child: new Text("Row ${widgets[i]["title"]}"));
}
loadData() async {
String dataURL = "https://api.iw3c.com/data";
http.Response response = await http.get(dataURL);
setState(() {
widgets = json.decode(response.body);
});
}
}
2. 使用第三方的package
我们需要用到一个第三方的package,名字叫:modal_progress_hud
import 'package:flutter/material.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyAPP',
theme: new ThemeData(
primarySwatch: Colors.red
),
home: new MyAppHomePage()
);
}
}
class MyAppHomePage extends StatefulWidget{
@override
MyAppHomePageState createState() {
// TODO: implement createState
return new MyAppHomePageState();
}
}
class MyAppHomePageState extends State<MyAppHomePage>{
int _counter = 0;
bool _loading = false;
void _plusOne(){
setState(() {
_counter++;
_loading = !_loading;
});
}
void _stopLoading(){
setState(() {
_loading = false;
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: new Text('测试按钮'),
centerTitle: true,
actions: [
new IconButton(
icon: new Icon(Icons.close),
onPressed: _stopLoading
)
],
),
body: ModalProgressHUD(
inAsyncCall: _loading,
opacity: 0.5,
progressIndicator: LinearProgressIndicator(), // 三种 CircularProgressIndicator RefreshProgressIndicator LinearProgressIndicator
child: new Row(
children: [
new RaisedButton(
onPressed: null,
child: new Text('Button $_counter'),
),
new FloatingActionButton(
onPressed: _plusOne,
child: new Icon(Icons.plus_one),
)
],
)
),
);
}
}
效果如下: