news 2026/5/9 13:12:08

深入 Flutter 开发:构建一个带网络请求的天气应用(含完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入 Flutter 开发:构建一个带网络请求的天气应用(含完整代码)

标题:深入 Flutter 开发:构建一个带网络请求的天气应用(含完整代码)

引言

在移动开发领域,Flutter凭借其高性能、跨平台能力和出色的 UI 表现力,已成为 Google 主推的现代应用开发框架。它使用 Dart 语言,通过自绘引擎 Skia 实现原生级渲染,支持一套代码运行在 iOS、Android、Web 和桌面端。

本文将带你从零开始,使用 Flutter 构建一个真实的天气查询应用,涵盖 UI 布局、HTTP 请求、JSON 解析、状态管理与错误处理,并附有完整可运行代码。


一、环境准备

确保已安装:

  • Flutter SDK(v3.19+)
  • Dart
  • 编辑器(推荐 VS Code 或 Android Studio)
  • 模拟器或真机调试设备

创建项目:

flutter create flutter_weather_appcdflutter_weather_app

二、添加依赖

编辑pubspec.yaml文件,添加网络请求和图标支持:

dependencies:flutter:sdk:flutterhttp:^1.0.0# 用于发送 HTTP 请求intl:^0.19.0# 格式化日期等(可选)

保存后运行:

flutter pub get

三、获取免费天气 API

我们使用 OpenWeatherMap 的免费 API:

  1. 注册账号并获取API Key
  2. 使用如下接口:
    https://api.openweathermap.org/data/2.5/weather?q=城市名&appid=你的APIKey&units=metric&lang=zh_cn

示例响应(JSON):

{"name":"Beijing","main":{"temp":22.5,"humidity":60},"weather":[{"description":"晴朗","icon":"01d"}]}

四、项目结构

lib/ ├── main.dart ├── models/ │ └── weather.dart ├── services/ │ └── weather_service.dart └── screens/ └── weather_screen.dart

五、完整代码实现

1. 模型类:models/weather.dart
// lib/models/weather.dartclassWeather{finalString cityName;finaldouble temperature;finalString description;finalString iconCode;Weather({requiredthis.cityName,requiredthis.temperature,requiredthis.description,requiredthis.iconCode,});// 工厂构造函数:从 JSON 创建对象factoryWeather.fromJson(Map<String,dynamic>json){returnWeather(cityName:json['name'],temperature:json['main']['temp'].toDouble(),description:json['weather'][0]['description'],iconCode:json['weather'][0]['icon'],);}}

2. 网络服务:services/weather_service.dart
// lib/services/weather_service.dartimport'dart:convert';import'package:http/http.dart'ashttp;import'../models/weather.dart';classWeatherService{finalString apiKey;WeatherService(this.apiKey);Future<Weather>fetchWeather(String city)async{finalurl=Uri.parse('https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$apiKey&units=metric&lang=zh_cn');finalresponse=awaithttp.get(url);if(response.statusCode==200){returnWeather.fromJson(json.decode(response.body));}else{throwException('Failed to load weather data');}}}

3. 主界面:screens/weather_screen.dart
// lib/screens/weather_screen.dartimport'package:flutter/material.dart';import'../models/weather.dart';import'../services/weather_service.dart';classWeatherScreenextendsStatefulWidget{constWeatherScreen({super.key});@overrideState<WeatherScreen>createState()=>_WeatherScreenState();}class_WeatherScreenStateextendsState<WeatherScreen>{finalTextEditingController _controller=TextEditingController();Weather?_weather;bool _loading=false;String?_error;// 替换为你的 OpenWeatherMap API KeyfinalWeatherService service=WeatherService("YOUR_API_KEY_HERE");void_searchWeather()async{finalcity=_controller.text.trim();if(city.isEmpty)return;setState((){_loading=true;_error=null;});try{finalweather=awaitservice.fetchWeather(city);setState((){_weather=weather;_loading=false;});}catch(e){setState((){_error=e.toString();_loading=false;});}}@overrideWidgetbuild(BuildContext context){returnScaffold(appBar:AppBar(title:constText("🌦️ 天气预报"),centerTitle:true,),body:Padding(padding:constEdgeInsets.all(16.0),child:Column(children:[// 输入框 + 搜索按钮Row(children:[Expanded(child:TextField(controller:_controller,decoration:constInputDecoration(labelText:'输入城市名称',border:OutlineInputBorder(),),onSubmitted:(_)=>_searchWeather(),),),constSizedBox(width:8),ElevatedButton(onPressed:_searchWeather,child:constIcon(Icons.search),),],),constSizedBox(height:20),// 加载状态if(_loading)constCircularProgressIndicator()elseif(_error!=null)Text('错误: $_error',style:TextStyle(color:Colors.red[700]),)elseif(_weather!=null)_buildWeatherCard(_weather!)elseconstText("请输入城市查询天气")],),),);}// 显示天气信息卡片Widget_buildWeatherCard(Weather weather){returnCard(elevation:4,child:Container(padding:constEdgeInsets.all(20),child:Column(crossAxisAlignment:CrossAxisAlignment.center,children:[Text(weather.cityName,style:constTextStyle(fontSize:28,fontWeight:FontWeight.bold),),constSizedBox(height:10),Image.network('https://openweathermap.org/img/wn/${weather.iconCode}@2x.png',width:100,height:100,),Text('${weather.temperature.toStringAsFixed(1)}°C',style:constTextStyle(fontSize:40,color:Colors.orange),),Text(weather.description,style:constTextStyle(fontSize:18,color:Colors.grey),),],),),);}@overridevoiddispose(){_controller.dispose();super.dispose();}}

4. 入口文件:main.dart
// lib/main.dartimport'package:flutter/material.dart';import'screens/weather_screen.dart';voidmain(){runApp(constMyApp());}classMyAppextendsStatelessWidget{constMyApp({super.key});@overrideWidgetbuild(BuildContext context){returnMaterialApp(title:'Flutter 天气应用',theme:ThemeData(primarySwatch:Colors.blue,useMaterial3:true,),home:constWeatherScreen(),debugShowCheckedModeBanner:false,);}}

六、运行应用

flutter run

在输入框中输入城市如 “Shanghai” 或 “纽约”,点击搜索,即可看到实时天气信息。


七、核心知识点总结

技术点说明
StatefulWidget用于需要动态更新的界面(如加载、数据变化)
http.get()发送网络请求获取天气数据
Futureasync/await异步处理网络调用
setState()触发 UI 重绘
TextFormField用户输入处理
JSON 解析使用factory构造函数映射 API 响应
错误处理try-catch 捕获异常并友好提示

八、优化建议(进阶方向)

  • ✅ 使用Provider/Riverpod进行全局状态管理
  • ✅ 添加地理位置定位自动获取城市
  • ✅ 支持天气图标本地缓存
  • ✅ 增加未来几天预报(调用 5-day forecast API)
  • ✅ 支持主题切换(深色/浅色模式)

九、结语

通过这个实战项目,你已经掌握了 Flutter 应用开发的核心流程:
UI 构建 → 网络请求 → 数据解析 → 状态更新 → 用户交互

Flutter 不仅让跨平台开发变得简单高效,更以接近原生的性能和丰富的组件生态,成为现代移动开发的理想选择。

🎯 下一步:将本项目部署到 Web 平台(flutter build web),让你的天气应用在浏览器中也能运行!


📌 提示:请将YOUR_API_KEY_HERE替换为你在 OpenWeatherMap 获取的真实密钥。

GitHub 示例地址(参考):github.com/yourname/flutter-weather


本文代码已在 Flutter 3.22 上测试通过,支持 Android、iOS 与 Web 平台。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 13:10:38

微算法科技(NASDAQ MLGO)链下与机器学习融合:革新区块链可扩展性

区块链技术自诞生以来&#xff0c;凭借去中心化、不可篡改的特性&#xff0c;在金融、供应链、版权保护等领域展现出颠覆性潜力。然而&#xff0c;随着用户规模与交易量的指数级增长&#xff0c;传统区块链架构逐渐暴露出可扩展性不足的瓶颈。公链网络每秒处理几十笔交易的能力…

作者头像 李华
网站建设 2026/5/1 7:07:42

考虑风光出力的虚拟电厂和运营商的主从博弈,分别考虑电动汽车充放电,火电出力,储能设备充放电充放...

考虑风光出力的虚拟电厂和运营商的主从博弈&#xff0c;分别考虑电动汽车充放电&#xff0c;火电出力&#xff0c;储能设备充放电充放电价格等因素外层用改进粒子群算法&#xff0c;目标函数线性加权。最近在折腾虚拟电厂和运营商的主从博弈模型&#xff0c;发现把风光出力、电…

作者头像 李华
网站建设 2026/5/3 21:43:57

不囤货、不开店,如何用一部手机连接1000家品牌

凌晨四点,陈明被一通电话吵醒。电话那头是仓库老王急促的声音:“陈总,那批饼干还有三天过期,今天再处理不掉,就只能当垃圾扔了!” 这已经是这个月第三次了。陈明烦躁地挂掉电话,看着仓库里堆积如山的临期货,心里像压了块石头。他是华南地区某知名饼干品牌的代理商,手里…

作者头像 李华
网站建设 2026/5/4 0:50:53

vue基于Springboot框架二手车托运物流管理系统

目录已开发项目效果实现截图开发技术系统开发工具&#xff1a;核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/5/6 1:35:40

《Etsy 最狠的地方,不是封号,而是先让你注册成功》

如果你是第一次做 Etsy 买家账号&#xff0c;我可以先告诉你一个不太好听的事实&#xff1a; 你现在网上看到的注册教程&#xff0c;基本都已经失效了。 什么换个 IP 开无痕 一个邮箱一个号 这些在 Etsy 现在的风控体系里&#xff0c;几乎等于“裸奔注册”。一、新手最容易掉进…

作者头像 李华
网站建设 2026/5/3 16:18:39

IoTDB详解

IoTDB 全称为 Internet of Things Database&#xff0c;是一款由清华大学团队主导开发的开源时序数据库&#xff0c;专门为物联网&#xff08;IoT&#xff09;场景量身打造。简单来说&#xff0c;它就是为海量、高频的物联网设备数据 “量身定做的存储与管理管家”。一、核心定…

作者头像 李华