Menu
CoddyTech

认识 FutureBuilder

本课属于 Coddy Flutter 学习旅程的“数据与网络”单元。第 6 课,共 27 课。

大多数屏幕打开时就会加载数据,不需要点击按钮。Flutter 提供了一个用于显示 Future 的组件:FutureBuilder。你把 Future 传给它,每当 Future 的状态变化时,它都会重新构建屏幕。

FutureBuilder<String>(
  future: _message,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      return Text(snapshot.data!);
    }
    return const CircularProgressIndicator();
  },
)

snapshot 表示 Future 当前的状态。在答案到达之前,snapshot.hasData 为 false,因此会显示加载指示器。答案到达后,builder 会再次运行,snapshot.data 中保存着字符串。

snapshot.data 的类型是 String?:它可以是字符串,也可以是 null,因为一开始还没有数据。后面的 ! 表示“我检查过了,它不是 null”。只有在 hasData 之后才能使用它:如果值为 null,应用就会崩溃。

入门代码已经在 initState 中创建了一次 Future。屏幕打开时就会运行这个方法。late 表示 Dart 中的变量会在那里获得值,并且在使用之前就会完成赋值。下一课会说明为什么要把它放在那里。

challenge icon

挑战

中等

应用在 initState 中加载消息,但从未显示它。将占位的 Text 替换为用于 _message 的 FutureBuilder<String>:

  • 加载期间显示 CircularProgressIndicator
  • 消息到达后,以 24 号字体显示

亲手试试

import 'package:flutter/material.dart';

import 'api.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MessageScreen(),
    );
  }
}

class MessageScreen extends StatefulWidget {
  const MessageScreen({super.key});

  @override
  State<MessageScreen> createState() => _MessageScreenState();
}

class _MessageScreenState extends State<MessageScreen> {
  late Future<String> _message;

  @override
  void initState() {
    super.initState();
    _message = fetch('/message');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: const Text('The message goes here', style: TextStyle(fontSize: 24)),
      ),
    );
  }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

数据与网络中的所有课

自己练习: Flutter 在线编译器