Menu
CoddyTech

Tải lại dữ liệu bằng nút

Thuộc phần Dữ liệu và mạng trong hành trình Flutter của Coddy. Bài học 8 trên 27.

Để tải dữ liệu mới, hãy truyền cho FutureBuilder một future mới. Tạo future đó trong setState để màn hình được dựng lại với nó:

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

Gợi ý mới sẽ xuất hiện sau 2 giây. Trong lúc tải, snapshot.hasData vẫn là true: builder giữ dữ liệu cũ cho đến khi dữ liệu mới thay thế nó. Khi kiểm tra hasData, gợi ý cũ vẫn hiển thị trên màn hình và không có gì cho biết ứng dụng đang hoạt động.

Để hiển thị lại vòng xoay tải, hãy kiểm tra snapshot.connectionState để biết future hiện đang ở trạng thái nào. Trạng thái này là ConnectionState.waiting khi future đang chạy và ConnectionState.done khi future đã hoàn tất:

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

Khi future hoàn tất, dữ liệu đã có, vì vậy snapshot.data! an toàn.

challenge icon

Thử thách

Trung bình

Thêm một nút làm mới để tải mẹo tiếp theo:

  • một IconButton với Icons.refresh trong actions của thanh trên cùng
  • khi nhấn, nút đặt _tip thành fetch('/tip') mới trong setState
  • vòng xoay hiển thị trong khi mẹo mới tải: kiểm tra snapshot.connectionState

Tự làm thử

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 iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Dữ liệu và mạng

Tự luyện tập: Trình biên dịch Flutter online