Menu
CoddyTech

Обновление свайпом вниз

Часть раздела Данные и сеть путешествия по 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.

challenge icon

Задание

Средне

Сделай так, чтобы подсказка загружалась заново, когда ты потянешь экран вниз:

  • добавь метод 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();
              },
            ),
        ),
      ),
    );
  }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Данные и сеть

Потренируйтесь самостоятельно: Онлайн-компилятор Flutter