Обновление свайпом вниз
Часть раздела Данные и сеть путешествия по Flutter на Coddy. Урок 9 из 27.
На телефоне люди тянут список вниз, чтобы перезагрузить его. Сверху появляется индикатор загрузки, и данные обновляются. Для этого во Flutter есть виджет RefreshIndicator:
RefreshIndicator(
onRefresh: refresh,
child: ListView(
children: [ ... ],
),
)onRefresh — это функция, которая возвращает Future. Индикатор загрузки при вытягивании остается, пока эта задача не завершится, поэтому используйте await для получения новых данных внутри функции:
Future<void> refresh() async {
setState(() {
_tip = fetch('/tip');
});
await _tip;
}Потянуть вниз можно только то, что прокручивается. Поместите содержимое в ListView, даже если в нем всего один элемент: ListView всегда можно потянуть вниз. Индикатор загрузки уже показывает, что приложение работает, поэтому билдер может оставить старую подсказку, проверяя hasData.
Задание
СреднеСделай так, чтобы подсказка загружалась заново, когда ты потянешь экран вниз:
- добавь метод
refresh, который задаёт новое значение_tipвsetStateи ожидает его завершения - оберни body в
RefreshIndicatorс параметромonRefresh: refresh - помести
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();
},
),
),
),
);
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Данные и сеть
1Future (асинхронные результаты)
Значение, которое появится позжеОжидание с async и awaitФункции, возвращающие FutureПрактический API Coddy2Экраны загрузки
Индикатор во время загрузкиЗнакомство с FutureBuilderЗагрузка данных один раз в initStateПерезагрузка данных кнопкойОбновление свайпом вниз3Когда вызовы завершаются ошибкой
Перехват ошибок с помощью tryВыбрасывание ошибкиОчистка с помощью finallyСостояние ошибки в FutureBuilderКнопка «Попробовать снова»Потренируйтесь самостоятельно: Онлайн-компилятор Flutter