Menu
CoddyTech

用按钮重新加载数据

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

要加载新数据,请给 FutureBuilder 一个新的 future。在 setState 中创建它,这样屏幕就会用它重新构建:

IconButton(
  icon: const Icon(Icons.refresh),
  onPressed: () {
    setState(() {
      _tip = fetch('/tip');
    });
  },
)

新的提示会在 2 秒后到达。加载期间,snapshot.hasData 仍然是 true:构建器会保留旧数据,直到新数据替换它。使用 hasData 检查时,旧提示会留在屏幕上,而且不会显示应用正在处理的状态。

要再次显示加载指示器,请检查 snapshot.connectionState,了解 Future 当前所处的状态。Future 运行期间,它的状态是 ConnectionState.waiting;完成后,状态是 ConnectionState.done:

if (snapshot.connectionState == ConnectionState.waiting) {
  return const CircularProgressIndicator();
}
return Text(snapshot.data!);

完成后,数据就已就绪,因此可以安全地使用 snapshot.data!。

challenge icon

挑战

中等

添加一个刷新按钮,用来加载下一条提示:

  • 在顶部栏的 actions 中添加一个带有 Icons.refresh 的 IconButton
  • 按下按钮后,在 setState 中将 _tip 设置为新的 fetch('/tip')
  • 加载新提示时显示加载指示器:检查 snapshot.connectionState

亲手试试

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: TipScreen(),
    );
  }
}

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

  @override
  State<TipScreen> createState() => _TipScreenState();
}

class _TipScreenState extends State<TipScreen> {
  late Future<String> _tip;

  @override
  void initState() {
    super.initState();
    _tip = fetch('/tip');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Tip of the Day'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: FutureBuilder<String>(
              future: _tip,
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  return Text(
                    snapshot.data!,
                    textAlign: TextAlign.center,
                    style: const TextStyle(fontSize: 24),
                  );
                }
                return const CircularProgressIndicator();
              },
            ),
        ),
      ),
    );
  }
}
quiz icon自我测试

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

数据与网络中的所有课

自己练习: Flutter 在线编译器