Menu
CoddyTech

FutureBuilder 的错误状态

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

FutureBuilder 会帮你捕获错误。当它的 future 抛出错误时,程序不会崩溃:builder 会再次运行,此时 snapshot.hasError 被设为 true,而 snapshot.error 保存着抛出的内容。

这样,每个加载界面都有三种状态,builder 会分别处理它们:

if (snapshot.hasError) {
  return Text('Could not load: ${snapshot.error}');
}
if (snapshot.hasData) {
  return Text(snapshot.data!);
}
return const CircularProgressIndicator();

错误、有数据,以及仍在加载。如果 builder 只处理有数据的情况,那么调用失败时就会永远显示加载指示器,因为根本不会有数据。

把每个检查都放在会跳过它的 return 之前。如果针对“没有数据”的加载指示器 return 在前面,那么它下面的错误代码行永远不会运行。

要在预览中查看失败情况,请在 main 的第一行写入 offline = true;,然后按“运行”。offline 来自 api.dart:它会让每次调用都失败,就像手机没有信号一样。按“检查”之前,请删除这一行。

challenge icon

挑战

中等

没有网络连接时,这个屏幕会一直转圈。为 builder 添加错误状态:当 snapshot.hasError 为 true 时,显示 Could not load: ,后面接上 snapshot.error,字号设为 20。

亲手试试

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: FutureBuilder<String>(
          future: _message,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Text(snapshot.data!, style: const TextStyle(fontSize: 24));
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}
quiz icon自我测试

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

数据与网络中的所有课

自己练习: Flutter 在线编译器