Menu
CoddyTech

天気アプリ:現在の天気

CoddyのFlutterジャーニー「データとネットワーク」セクションの一部。レッスン 23/27。

このセクションでは、天気アプリというアプリ全体を作っていきます。これからの5つのレッスンでは、ある都市の現在の天気と今後3日間の天気、それぞれのアイコン、「もう一度試す」ボタンのあるエラー画面、そして都市選択画面を表示します。

練習用APIでは3つの都市を利用できます。/weather/lisbonの応答は次のとおりです。

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

画面の上部から始め、これまでに学んだ手順を使いましょう。データ用のクラス、データを取得してデコードする関数、initStateで一度だけ作成するfuture、そして3つの状態を扱うFutureBuilderです。ファイルの末尾にあるWeatherクラスとDayForecastクラス、およびそれらのfromJsonは、あらかじめ用意されています。このレッスンでは現在の天気を表示します。天気予報は次のレッスンで扱います。

challenge icon

チャレンジ

難しい

リスボンの天気を表示します。

  • loadWeather は /weather/lisbon を取得し、Weather.fromJson(jsonDecode(body)) を返します
  • initState で future を一度だけ作成します
  • FutureBuilder<Weather> は、読み込み中はスピナーを表示し、失敗した場合は Could not load: とエラーを表示します
  • データがある場合は、都市名(サイズ 32)、度記号付きの気温 21°(サイズ 72、太字)、および天気の状態(サイズ 24)を Column に表示します

自分で試してみよう

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 icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

データとネットワークのすべてのレッスン

自分で練習してみよう: Flutterオンラインコンパイラ