下拉刷新
本课属于 Coddy Flutter 学习旅程的“数据与网络”单元。第 9 课,共 27 课。
在手机上,人们会向下拉动列表来重新加载。一个旋转指示器会从顶部落下,数据也会更新。Flutter 提供的对应组件是 RefreshIndicator:
RefreshIndicator(
onRefresh: refresh,
child: ListView(
children: [ ... ],
),
)onRefresh 是一个返回 Future 的函数。拉动时的旋转指示器会一直显示,直到这个 future 完成,所以要在其中用 await 等待新数据:
Future<void> refresh() async {
setState(() {
_tip = fetch('/tip');
});
await _tip;
}只有可滚动的内容才能响应下拉操作。把内容放进 ListView,即使只有一项也一样:ListView 总是可以下拉的。下拉时的旋转指示器已经表明应用正在工作,因此构建器可以通过 hasData 检查来保留旧提示。
挑战
中等下拉屏幕时,让提示重新加载:
- 添加一个
refresh方法,在setState中设置新的_tip,并等待它完成 - 用带有
onRefresh: refresh的RefreshIndicator包裹主体内容 - 将
FutureBuilder放在其中的ListView里
在预览中,用鼠标向下拖动屏幕。
亲手试试
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();
},
),
),
),
);
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
数据与网络中的所有课
自己练习: Flutter 在线编译器