天气应用:此刻
本课属于 Coddy Flutter 学习旅程的“数据与网络”单元。第 23 课,共 27 课。
是时候用本单元的内容构建一个完整的应用了:天气应用。在接下来的 5 节课中,它会显示一个城市当前的天气、未来 3 天的天气、每天对应的图标、带有“再试一次”按钮的错误界面,以及城市选择器。
练习 API 支持 3 个城市。/weather/lisbon会返回:
{
"city": "Lisbon",
"temperature": 21,
"condition": "Sunny",
"forecast": [ ... ]
}先从屏幕顶部开始,按照你已经掌握的步骤来做:创建一个用于存放数据的类,编写一个用于获取和解码数据的函数,在 initState 中创建一次 Future,并使用 FutureBuilder 处理它的 3 种状态。文件底部的 Weather 和 DayForecast 类及其 fromJson 已经为你编写好了。本课将显示当前天气,下一课会介绍天气预报。
挑战
困难显示里斯本的天气:
loadWeather获取/weather/lisbon,并返回Weather.fromJson(jsonDecode(body))- 在
initState中创建一次 Future FutureBuilder<Weather>会在加载时显示加载指示器;如果加载失败,则显示Could not load:和错误信息- 有数据时,显示一个
Column,其中包括城市(字号 32)、带度数符号的温度21°(字号 72、加粗)和天气状况(字号 24)
亲手试试
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,
);
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
数据与网络中的所有课
自己练习: Flutter 在线编译器