在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),
                        )
                    ],
                )
            ),
		);
  }
}

效果如下:

图1图2

图3