异步请求之后渲染页面

在 Flutter 中,经常遇到先进行网络请求,然后用请求成功返回的结果来渲染页面的场景。如果网络请求速度比较慢的话,需要在等待网络返回结果的时候,给用户渲染一个等待的页面。有两种方式:

  1. 使用 FutureBuilder 组件

    封装好了这类组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    new FutureBuilder(
    future: _future, // Future 对象或 null
    builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
    switch (snapshot.connectionState) {
    case ConnectionState.none: return new Text('Press button to start');
    case ConnectionState.waiting: return new Text('Awaiting result...');
    default:
    if (snapshot.hasError)
    return new Text('Error: ${snapshot.error}');
    else
    return new Text('Result: ${snapshot.data}');
    }
    },
    )
  2. 定义变量,然后用 setState 来刷新

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    class MyHomePage extends StatefulWidget {
    MyHomePage({Key key, this.title}) : super(key: key);

    final String title;

    @override
    _MyHomePageState createState() => new _MyHomePageState();
    }

    class _MyHomePageState extends State<MyHomePage> {
    List data;

    @override
    initState() {
    super.initState();
    new Future<String>.delayed(new Duration(seconds: 5), () => '["123", "456", "789"]').then((String value) {
    setState(() {
    data = json.decode(value);
    });
    });
    }

    @override
    Widget build(BuildContext context) {
    if (data == null) {
    return new Scaffold(
    appBar: new AppBar(
    title: new Text("Loading..."),
    ),
    );
    } else {
    return new Scaffold(
    appBar: new AppBar(
    title: new Text(widget.title),
    ),
    body: new Center(
    child: new ListView(
    children: data
    .map((data) => new ListTile(
    title: new Text("one element"),
    subtitle: new Text(data),
    ))
    .toList(),
    ),
    ),
    );
    }
    }
    }