Flutter 跨平台实战鸿蒙 6.0 (API20) 集成三方库开发天气查询应用前言对于鸿蒙开发者入门 Flutter 跨平台开发借助成熟三方库可以快速实现复杂功能。本文以跨平台天气查询应用为案例在鸿蒙 6.0 (API20) 环境下集成网络请求、JSON 解析、位置获取、UI 美化三方库完成可落地的跨端应用。一、环境配置要求Flutter 3.16 及以上版本DevEco Studio 搭载鸿蒙 6.0 (API20) 模拟器 / 真机开启网络权限、定位权限代码编辑器Android Studio / VS Code二、项目创建与鸿蒙适配配置1. 创建 Flutter 项目flutter create flutter\_harmony\_weather cd flutter\_harmony\_weather2. 鸿蒙 6.0 适配配置修改android/app/build.gradle匹配鸿蒙底层适配要求android { #x20; compileSdkVersion 33 #x20; defaultConfig { #x20; applicationId com.example.flutter\_harmony\_weather #x20; minSdkVersion 21 #x20; targetSdkVersion 33 #x20; versionCode 1 #x20; versionName 1.0 #x20; } }3. 权限配置打开android/app/src/main/AndroidManifest.xml添加权限\!-- 网络权限 -- \uses-permission android:nameandroid.permission.INTERNET/ \!-- 定位权限 -- \uses-permission android:nameandroid.permission.ACCESS\_FINE\_LOCATION/ \uses-permission android:nameandroid.permission.ACCESS\_COARSE\_LOCATION/三、引入兼容鸿蒙的三方库本次选用在鸿蒙 6.0 上运行稳定的常用库在pubspec.yaml中添加依赖dependencies: #x20; flutter: #x20; sdk: flutter #x20; \# 网络请求三方库 #x20; dio: ^5.4.0 #x20; \# 定位获取三方库 #x20; geolocator: ^10.1.0 #x20; \# 加载状态提示库 #x20; flutter\_easyloading: ^3.0.5 #x20; \# 图标美化库 #x20; font\_awesome\_flutter: ^10.6.0执行依赖安装命令flutter pub get四、项目结构规划lib/ ├── main.dart # 应用入口 ├── models/weather\_model.dart # 天气数据模型 ├── utils/api\_util.dart # 网络请求工具 ├── pages/weather\_page.dart # 主页面五、代码实现1. 天气数据模型models/weather_model.dart解析接口返回的 JSON 数据结构化存储天气信息/// 天气数据模型 class WeatherModel { #x20; final String city; // 城市 #x20; final String temp; // 温度 #x20; final String weather; // 天气状况 #x20; final String wind; // 风力 #x20; final String humidity; // 湿度 #x20; WeatherModel({ #x20; required this.city, #x20; required this.temp, #x20; required this.weather, #x20; required this.wind, #x20; required this.humidity, #x20; }); #x20; // 解析JSON数据此处适配简易天气接口 #x20; factory WeatherModel.fromJson(Map\String, dynamic json) { #x20; return WeatherModel( #x20; city: json\[city] ?? 未知城市, #x20; temp: json\[temp] ?? N/A, #x20; weather: json\[weather] ?? 未知天气, #x20; wind: json\[wind] ?? N/A, #x20; humidity: json\[humidity] ?? N/A, #x20; ); #x20; } }2. 网络请求工具utils/api_util.dart基于 dio 三方库实现网络请求封装获取天气方法import package:dio/dio.dart; import ../models/weather\_model.dart; class ApiUtil { #x20; final Dio \_dio Dio(); #x20; /// 获取指定城市天气 #x20; Future\WeatherModel getWeather(String city) async { #x20; try { #x20; // 免费天气接口可自行替换为正规天气API #x20; final response await \_dio.get( #x20; https://api.example.com/weather, #x20; queryParameters: {city: city}, #x20; ); #x20; return WeatherModel.fromJson(response.data); #x20; } catch (e) { #x20; rethrow; #x20; } #x20; } }3. 主页面实现pages/weather_page.dart集成定位、网络请求、加载提示三方库实现核心交互import package:flutter/material.dart; import package:geolocator/geolocator.dart; import package:flutter\_easyloading/flutter\_easyloading.dart; import package:font\_awesome\_flutter/font\_awesome\_flutter.dart; import ../utils/api\_util.dart; import ../models/weather\_model.dart; class WeatherPage extends StatefulWidget { #x20; const WeatherPage({super.key}); #x20; override #x20; State\WeatherPage createState() \_WeatherPageState(); } class \_WeatherPageState extends State\WeatherPage { #x20; final ApiUtil \_apiUtil ApiUtil(); #x20; WeatherModel? \_weatherModel; #x20; final TextEditingController \_cityController TextEditingController(); #x20; override #x20; void initState() { #x20; super.initState(); #x20; // 初始化加载提示组件 #x20; EasyLoading.init(); #x20; } #x20; /// 获取定位权限并定位当前城市 #x20; Future\void getLocationWeather() async { #x20; EasyLoading.show(status: 获取定位中...); #x20; // 检查定位权限 #x20; bool serviceEnabled await Geolocator.isLocationServiceEnabled(); #x20; if (!serviceEnabled) { #x20; EasyLoading.showError(定位服务未开启); #x20; return; #x20; } #x20; LocationPermission permission await Geolocator.checkPermission(); #x20; if (permission LocationPermission.denied) { #x20; permission await Geolocator.requestPermission(); #x20; if (permission LocationPermission.denied) { #x20; EasyLoading.showError(定位权限被拒绝); #x20; return; #x20; } #x20; } #x20; if (permission LocationPermission.deniedForever) { #x20; EasyLoading.showError(权限永久拒绝无法定位); #x20; return; #x20; } #x20; // 获取定位坐标实际开发可通过经纬度获取城市 #x20; Position position await Geolocator.getCurrentPosition(); #x20; await getWeatherData(北京); #x20; } #x20; /// 获取天气数据 #x20; Future\void getWeatherData(String city) async { #x20; if (city.isEmpty) { #x20; EasyLoading.showInfo(请输入城市名称); #x20; return; #x20; } #x20; EasyLoading.show(status: 加载天气中...); #x20; try { #x20; final data await \_apiUtil.getWeather(city); #x20; setState(() { #x20; \_weatherModel data; #x20; }); #x20; EasyLoading.showSuccess(加载成功); #x20; } catch (e) { #x20; EasyLoading.showError(获取天气失败\${e.toString()}); #x20; } #x20; } #x20; override #x20; Widget build(BuildContext context) { #x20; return Scaffold( #x20; appBar: AppBar( #x20; title: const Text(Flutter鸿蒙天气查询), #x20; centerTitle: true, #x20; ), #x20; body: SingleChildScrollView( #x20; padding: const EdgeInsets.all(20), #x20; child: Column( #x20; children: \[ #x20; // 城市输入框 #x20; TextField( #x20; controller: \_cityController, #x20; decoration: InputDecoration( #x20; hintText: 请输入城市名称, #x20; suffixIcon: IconButton( #x20; icon: const Icon(Icons.search), #x20; onPressed: () { #x20; getWeatherData(\_cityController.text.trim()); #x20; }, #x20; ), #x20; border: const OutlineInputBorder(), #x20; ), #x20; ), #x20; const SizedBox(height: 15), #x20; // 定位获取天气按钮 #x20; ElevatedButton.icon( #x20; onPressed: getLocationWeather, #x20; icon: const FaIcon(FontAwesomeIcons.locationCrosshairs), #x20; label: const Text(定位获取当前天气), #x20; ), #x20; const SizedBox(height: 30), #x20; // 天气信息展示区域 #x20; if (\_weatherModel ! null) #x20; Card( #x20; elevation: 5, #x20; shape: RoundedRectangleBorder( #x20; borderRadius: BorderRadius.circular(15), #x20; ), #x20; child: Padding( #x20; padding: const EdgeInsets.all(25), #x20; child: Column( #x20; children: \[ #x20; Text( #x20; \_weatherModel!.city, #x20; style: const TextStyle( #x20; fontSize: 24, fontWeight: FontWeight.bold), #x20; ), #x20; const SizedBox(height: 20), #x20; Text( #x20; \${\_weatherModel!.temp}℃, #x20; style: const TextStyle(fontSize: 40), #x20; ), #x20; const SizedBox(height: 10), #x20; Text( #x20; \_weatherModel!.weather, #x20; style: const TextStyle(fontSize: 20), #x20; ), #x20; const Divider(height: 30), #x20; Row( #x20; mainAxisAlignment: MainAxisAlignment.spaceAround, #x20; children: \[ #x20; \_weatherItem( #x20; FontAwesomeIcons.wind, #x20; 风力, #x20; \_weatherModel!.wind, #x20; ), #x20; \_weatherItem( #x20; FontAwesomeIcons.droplet, #x20; 湿度, #x20; \_weatherModel!.humidity, #x20; ), #x20; ], #x20; ), #x20; ], #x20; ), #x20; ), #x20; ), #x20; ], #x20; ), #x20; ), #x20; ); #x20; } #x20; /// 天气信息子项 #x20; Widget \_weatherItem(IconData icon, String title, String value) { #x20; return Column( #x20; children: \[ #x20; FaIcon(icon, size: 25), #x20; const SizedBox(height: 5), #x20; Text(title), #x20; Text(value), #x20; ], #x20; ); #x20; } }4. 应用入口main.dart全局配置加载提示挂载主页面import package:flutter/material.dart; import package:flutter\_easyloading/flutter\_easyloading.dart; import pages/weather\_page.dart; void main() { #x20; runApp(const MyApp()); } class MyApp extends StatelessWidget { #x20; const MyApp({super.key}); #x20; override #x20; Widget build(BuildContext context) { #x20; return MaterialApp( #x20; title: Flutter鸿蒙天气, #x20; theme: ThemeData(primarySwatch: Colors.blue), #x20; home: const WeatherPage(), #x20; // 配置加载提示三方库 #x20; builder: EasyLoading.init(), #x20; debugShowCheckedModeBanner: false, #x20; ); #x20; } }六、鸿蒙 6.0 (API20) 运行步骤启动 DevEco Studio 中鸿蒙 6.0 API20 模拟器连接设备后执行运行命令flutter run授予应用定位、网络权限输入城市或使用定位功能获取天气信息七、三方库在鸿蒙平台的使用说明dio网络请求无兼容问题可正常请求天气接口geolocator适配鸿蒙定位服务可成功获取设备位置flutter_easyloading加载弹窗在鸿蒙设备渲染正常font_awesome_flutter矢量图标完美展示八、开发注意事项正式开发需替换为合规商用天气 API替换接口地址即可鸿蒙设备需手动开启应用权限否则定位功能无法使用网络请求需处理异常情况提升应用稳定性九、总结本项目完整展示了Flutter 结合三方库开发鸿蒙 6.0 应用的全流程贴合实际开发场景。借助 Flutter 跨平台特性一套代码可同时运行在 Android、iOS、鸿蒙设备上大幅降低鸿蒙应用开发成本。