Menu
CoddyTech

Ứng dụng thời tiết: hiện tại

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

Đã đến lúc xây dựng một ứng dụng hoàn chỉnh từ phần này: ứng dụng thời tiết. Trong năm bài học tiếp theo, ứng dụng sẽ hiển thị thời tiết hiện tại của một thành phố, dự báo cho ba ngày tới, biểu tượng cho từng ngày, màn hình lỗi có nút Thử lại và bộ chọn thành phố.

API thực hành có dữ liệu của ba thành phố. /weather/lisbon trả về:

{
  "city": "Lisbon",
  "temperature": 21,
  "condition": "Sunny",
  "forecast": [ ... ]
}

Bắt đầu với phần trên cùng của màn hình và những bước bạn đã biết: một lớp cho dữ liệu, một hàm lấy và giải mã dữ liệu, một future được tạo một lần trong initState và một FutureBuilder với ba trạng thái. Các lớp Weather và DayForecast ở cuối tệp đã được viết sẵn cho bạn, cùng với fromJson của chúng. Bài học này trình bày thời tiết hiện tại; phần dự báo sẽ có trong bài học tiếp theo.

challenge icon

Thử thách

Khó

Hiển thị thời tiết ở Lisbon:

  • loadWeather lấy dữ liệu từ /weather/lisbon và trả về Weather.fromJson(jsonDecode(body))
  • tạo future một lần trong initState
  • FutureBuilder<Weather> hiển thị vòng tròn tải trong khi tải dữ liệu, rồi hiển thị Could not load: cùng lỗi nếu tải thất bại
  • khi có dữ liệu, hiển thị Column gồm tên thành phố (cỡ 32), nhiệt độ có dấu độ, 21° (cỡ 72, in đậm) và điều kiện thời tiết (cỡ 24)

Tự làm thử

import 'dart:convert';

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: WeatherScreen(),
    );
  }
}

class WeatherScreen extends StatefulWidget {
  const WeatherScreen({super.key});

  @override
  State<WeatherScreen> createState() => _WeatherScreenState();
}

class _WeatherScreenState extends State<WeatherScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Weather')),
      body: const Center(
        child: Text('The weather goes here'),
      ),
    );
  }
}

class Weather {
  Weather({
    required this.city,
    required this.temperature,
    required this.condition,
    required this.forecast,
  });

  final String city;
  final int temperature;
  final String condition;
  final List<DayForecast> forecast;

  factory Weather.fromJson(Map<String, dynamic> json) {
    final days = json['forecast'] as List<dynamic>;
    return Weather(
      city: json['city'] as String,
      temperature: json['temperature'] as int,
      condition: json['condition'] as String,
      forecast: days
          .map((day) => DayForecast.fromJson(day as Map<String, dynamic>))
          .toList(),
    );
  }
}

class DayForecast {
  DayForecast({
    required this.date,
    required this.condition,
    required this.high,
    required this.low,
  });

  final DateTime date;
  final String condition;
  final int high;
  final int low;

  factory DayForecast.fromJson(Map<String, dynamic> json) {
    return DayForecast(
      date: DateTime.parse(json['date'] as String),
      condition: json['condition'] as String,
      high: json['high'] as int,
      low: json['low'] as int,
    );
  }
}
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