Кнопка «Попробовать снова»
Часть раздела Данные и сеть путешествия по Flutter на Coddy. Урок 14 из 27.
Связь восстанавливается. Хороший экран ошибки не оставляет человека в тупике: он сообщает, что произошло, и предлагает попробовать ещё раз.
Повторная попытка — это перезагрузка: создай новый Future в setState, как при нажатии кнопки обновления.
void tryAgain() {
setState(() {
_message = fetch('/message');
});
}Есть один нюанс. Пока выполняется новый Future, снимок сохраняет последнюю ошибку, так же как он сохраняет старые данные: hasError остаётся равным true, пока не поступит новый ответ. Чтобы во время второй попытки показывался индикатор загрузки, сначала проверь snapshot.connectionState:
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
}
if (snapshot.hasError) {
// ошибка и кнопка
}
return Text(snapshot.data!);Чтобы увидеть сбой в предварительном просмотре, добавь offline = true; первой строкой в main и нажми «Запустить». offline берётся из api.dart: из-за него каждый вызов завершается ошибкой, как будто на телефоне нет сигнала. Удали эту строку, прежде чем нажать «Проверить».
Задание
СреднеДобавь способ выйти из состояния ошибки:
- под текстом ошибки добавь кнопку Попробовать снова
- при нажатии на неё присвой новое значение
fetch('/message')внутриsetState - во время повторной попытки отображается индикатор загрузки: сначала проверь
ConnectionState.waitingв builder
Попробуйте сами
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.hasError) {
return Text(
'Could not load: ${snapshot.error}',
style: const TextStyle(fontSize: 20),
);
}
if (snapshot.hasData) {
return Text(snapshot.data!, style: const TextStyle(fontSize: 24));
}
return const CircularProgressIndicator();
},
),
),
);
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Данные и сеть
1Future (асинхронные результаты)
Значение, которое появится позжеОжидание с async и awaitФункции, возвращающие FutureПрактический API Coddy3Когда вызовы завершаются ошибкой
Перехват ошибок с помощью tryВыбрасывание ошибкиОчистка с помощью finallyСостояние ошибки в FutureBuilderКнопка «Попробовать снова»Потренируйтесь самостоятельно: Онлайн-компилятор Flutter