Menu
CoddyTech

Aplikacja pogodowa: najbliższe trzy dni

Część sekcji Dane i sieć ścieżki Flutter w Coddy. Lekcja 24 z 27.

Odpowiedź dotycząca miasta zawiera również prognozę: listę JSON wewnątrz obiektu, po jednym elemencie na każdy dzień.

"forecast": [
  {"date": "2026-10-20", "condition": "Cloudy", "high": 22, "low": 15},
  ...
]

Listę wewnątrz obiektu odczytuje się tak samo jak samodzielną listę: wyodrębnij ją jako as List<dynamic>, a następnie zastosuj map do każdego elementu, używając jego własnego fromJson. Zobacz Weather.fromJson na końcu pliku: ta metoda już to robi, więc weather.forecast jest typu List<DayForecast>.

final days = json['forecast'] as List<dynamic>;

forecast: days
    .map((day) => DayForecast.fromJson(day as Map<String, dynamic>))
    .toList(),

Każdy dzień ma wartość typu DateTime. DateFormat('EEEE') zamienia ją na pełną nazwę dnia tygodnia, na przykład „wtorek”. Pętla for wewnątrz elementu children komponentu Column tworzy jeden wiersz na każdy dzień.

challenge icon

Wyzwanie

Średni

Pod aktualną pogodą pokaż trzy kolejne dni:

  • zaimportuj package:intl/intl.dart
  • po SizedBox(height: 32) umieść jeden Row na każdy dzień: dzień tygodnia sformatowany za pomocą DateFormat('EEEE') w elemencie Expanded, a następnie temperaturę maksymalną i minimalną w formacie 22° / 15°
  • dodaj do każdego wiersza 32 piksele odstępu po lewej i prawej stronie

Spróbuj swoich sił

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> {
  late Future<Weather> _weather;

  @override
  void initState() {
    super.initState();
    _weather = loadWeather();
  }

  Future<Weather> loadWeather() async {
    final body = await fetch('/weather/lisbon');
    return Weather.fromJson(jsonDecode(body));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Weather')),
      body: Center(
        child: FutureBuilder<Weather>(
          future: _weather,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text('Could not load: ${snapshot.error}');
            }
            if (snapshot.hasData) {
              return buildWeather(snapshot.data!);
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }

  Widget buildWeather(Weather weather) {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(weather.city, style: const TextStyle(fontSize: 32)),
        Text(
          '${weather.temperature}°',
          style: const TextStyle(fontSize: 72, fontWeight: FontWeight.bold),
        ),
        Text(weather.condition, style: const TextStyle(fontSize: 24)),
      ],
    );
  }
}

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 iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Dane i sieć

Poćwicz samodzielnie: Kompilator Flutter online