Flutter+DevEco Studio实战:简易天气查询工具开发指南

跨平台开发与HarmonyOS生态融合的趋势下,利用Flutter快速构建UI、DevEco Studio适配HarmonyOS设备的开发模式,能有效提升应用开发效率。本文将以"简易天气查询工具"为案例,详细讲解Flutter与DevEco Studio结合开发的全流程,涵盖环境复用、项目搭建、网络请求、数据展示及HarmonyOS适配等核心环节,适合具备基础Flutter和HarmonyOS开发基础的开发者学习参考。

Flutter+DevEco Studio实战:简易天气查询工具开发指南大纲

项目背景与目标
  • 介绍Flutter框架的跨平台优势
  • DevEco Studio作为HarmonyOS开发工具的特点
  • 简易天气查询工具的功能需求和适用场景
开发环境配置
  • 安装Flutter SDK并配置环境变量
  • 安装DevEco Studio及HarmonyOS开发插件
  • 检查Flutter与DevEco Studio的兼容性
项目初始化
  • 使用Flutter CLI创建新项目
  • 在DevEco Studio中导入Flutter项目
  • 配置项目依赖(如http、provider等常用库)
界面设计与布局
  • 使用Flutter Widget构建主页面框架
  • 实现城市搜索输入框和查询按钮
  • 设计天气信息展示区域(温度、湿度、天气图标等)
数据获取与处理
  • 调用第三方天气API(如和风天气)
  • 解析返回的JSON数据并转换为Dart对象
  • 使用Provider或Bloc进行状态管理
功能逻辑实现
  • 实现城市搜索功能与API请求绑定
  • 处理网络请求异常和加载状态
  • 动态更新UI以反映天气数据变化
跨平台适配与优化
  • 检查HarmonyOS平台上的兼容性问题
  • 优化布局在不同设备上的显示效果
  • 测试应用在Android/iOS/HarmonyOS上的运行情况
调试与发布
  • 使用DevEco Studio的调试工具排查问题
  • 生成HarmonyOS应用发布包(.hap文件)
  • 上架到华为应用市场的简要流程说明
总结与扩展
  • 回顾关键技术点和解决方案
  • 提出进一步功能扩展建议(如多语言支持、天气预警等)
  • 推荐学习资源与社区支持

一、项目概述与环境复用

1.1 项目核心功能

本次开发的简易天气查询工具,实现3个核心功能:输入城市名称查询天气、展示实时温度/天气状况/风力等信息、处理网络异常与空输入提示。项目采用Flutter构建跨平台UI,通过第三方天气API获取数据,最终基于DevEco Studio适配HarmonyOS设备运行。

1.2 环境复用说明

本文复用前文"待办事项列表"项目的开发环境,无需重复配置。核心环境要求如下表所示,若环境未配置完成,可参考前文"前置知识与环境准备"章节完成配置:

工具名称 最低版本要求 核心作用
DevEco Studio 4.1.0.600 HarmonyOS设备适配、项目编译运行
Flutter SDK 3.16.0 构建统一风格的天气查询UI界面
Dart SDK 3.2.0 编写Flutter业务逻辑与网络请求代码
HarmonyOS SDK API Version 9 保障应用在HarmonyOS手机/模拟器正常运行

二、项目初始化与依赖配置

2.1 新建Flutter项目

  1. 打开DevEco Studio,选择File > New > New Flutter Project,选择"Flutter Application",点击"Next"。

  2. 配置项目信息:Project Name设为"flutter_harmony_weather",Package Name遵循HarmonyOS规范(如"com.example.flutterharmonyweather"),选择项目保存路径后点击"Finish"。

2.2 核心依赖配置

项目需引入网络请求、JSON解析相关依赖,修改pubspec.yaml文件,在dependencies节点下添加以下配置:

复制代码
dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.5  # 用于发送网络请求获取天气数据
  json_annotation: ^4.8.1  # 用于JSON数据模型序列化/反序列化
  flutter_harmony: ^0.1.0  # 保障Flutter与HarmonyOS兼容性

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.4.4  # 生成JSON解析相关代码
  json_serializable: ^6.7.0  # 配合json_annotation实现JSON解析

配置完成后,在终端执行flutter pub get拉取依赖,确保无依赖冲突。

三、核心功能实现

3.1 天气数据模型定义

选择"聚合数据"免费天气API(需提前注册获取API密钥),API返回数据包含城市、温度、天气状况等信息。在lib/models/weather_model.dart中定义数据模型,代码如下:

复制代码
import 'package:json_annotation/json_annotation.dart';

// 生成的解析代码会在该路径下,需先执行build_runner命令
part 'weather_model.g.dart';

@JsonSerializable()
class WeatherResponse {
  final int error_code; // 错误码,0表示成功
  final String reason; // 提示信息
  final WeatherResult result;

  WeatherResponse({
    required this.error_code,
    required this.reason,
    required this.result,
  });

  // 从JSON转换为模型对象
  factory WeatherResponse.fromJson(Map<String, dynamic> json) = _$WeatherResponseFromJson;
  // 从模型对象转换为JSON
  Map<String, dynamic> toJson() = _$WeatherResponseToJson;
}

@JsonSerializable()
class WeatherResult {
  final String city; // 城市名称
  final RealTimeWeather realtime; // 实时天气信息

  WeatherResult({required this.city, required this.realtime});

  factory WeatherResult.fromJson(Map<String, dynamic> json) = _$WeatherResultFromJson;
  Map<String, dynamic> toJson() = _$WeatherResultToJson;
}

@JsonSerializable()
class RealTimeWeather {
  final String info; // 天气状况(如晴、阴)
  final String temperature; // 实时温度
  final String humidity; // 湿度
  final String direct; // 风向
  final String power; // 风力

  RealTimeWeather({
    required this.info,
    required this.temperature,
    required this.humidity,
    required this.direct,
    required this.power,
  });

  factory RealTimeWeather.fromJson(Map<String, dynamic> json) = _$RealTimeWeatherFromJson;
  Map<String, dynamic> toJson() = _$RealTimeWeatherToJson;
}

执行flutter pub run build_runner build生成JSON解析代码(即weather_model.g.dart),若后续修改模型,需重新执行该命令。

3.2 网络请求工具类实现

lib/utils/network_utils.dart中封装网络请求工具类,统一处理请求发送与异常捕获:

复制代码
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/weather_model.dart';

class NetworkUtils {
  // 聚合数据天气API地址(替换为自己的API密钥)
  static const String _weatherApiUrl = "http://v.juhe.cn/weather/index?format=2&key=YOUR_API_KEY&cityname=";

  // 根据城市名称查询天气
  static Future<WeatherResponse?> fetchWeather(String cityName) async {
    try {
      final response = await http.get(Uri.parse(_weatherApiUrl + cityName));
      if (response.statusCode == 200) {
        // 解析JSON数据为模型对象
        return WeatherResponse.fromJson(json.decode(response.body));
      } else {
        print("网络请求失败,状态码:${response.statusCode}");
        return null;
      }
    } catch (e) {
      print("网络请求异常:$e");
      return null;
    }
  }
}

注意:将YOUR_API_KEY替换为自己在聚合数据平台获取的天气API密钥。

3.3 主页面UI与业务逻辑实现

lib/main.dart中实现天气查询主页面,包含城市输入框、查询按钮、天气信息展示区域,以及加载状态与异常提示:

复制代码
import 'package:flutter/material.dart';
import 'models/weather_model.dart';
import 'utils/network_utils.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter-Harmony天气查询',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const WeatherQueryPage(),
    );
  }
}

class WeatherQueryPage extends StatefulWidget {
  const WeatherQueryPage({super.key});

  @override
  State<WeatherQueryPage> createState() => _WeatherQueryPageState();
}

class _WeatherQueryPageState extends State<WeatherQueryPage> {
  final TextEditingController _cityController = TextEditingController();
  WeatherResult? _weatherResult; // 存储查询到的天气结果
  bool _isLoading = false; // 加载状态标识
  String _errorMsg = ""; // 错误提示信息

  // 查询天气方法
  void _queryWeather() {
    final cityName = _cityController.text.trim();
    if (cityName.isEmpty) {
      setState(() {
        _errorMsg = "请输入城市名称";
        _weatherResult = null;
      });
      return;
    }

    setState(() {
      _isLoading = true;
      _errorMsg = "";
    });

    // 调用网络工具类查询天气
    NetworkUtils.fetchWeather(cityName).then((response) {
      setState(() {
        _isLoading = false;
        if (response != null && response.error_code == 0) {
          _weatherResult = response.result;
        } else {
          _errorMsg = response?.reason ?? "查询失败,请重试";
          _weatherResult = null;
        }
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('简易天气查询')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            // 城市输入框与查询按钮
            Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _cityController,
                    decoration: const InputDecoration(
                      hintText: '请输入城市名称(如北京)',
                      border: OutlineInputBorder(),
                    ),
                  ),
                ),
                const SizedBox(width: 10),
                ElevatedButton(
                  onPressed: _isLoading ? null : _queryWeather,
                  child: _isLoading
                      ? const CircularProgressIndicator(color: Colors.white, strokeWidth: 2)
                      : const Text('查询'),
                ),
              ],
            ),
            const SizedBox(height: 20),
            // 错误提示
            if (_errorMsg.isNotEmpty)
              Text(
                _errorMsg,
                style: const TextStyle(color: Colors.red, fontSize: 14),
              ),
            // 天气信息展示区域
            if (_weatherResult != null)
              Expanded(
                child: Card(
                  elevation: 5,
                  child: Padding(
                    padding: const EdgeInsets.all(20.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          '城市:${_weatherResult!.city}',
                          style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                        ),
                        const SizedBox(height: 20),
                        Text('天气状况:${_weatherResult!.realtime.info}', style: const TextStyle(fontSize: 16)),
                        const SizedBox(height: 10),
                        Text('实时温度:${_weatherResult!.realtime.temperature}℃', style: const TextStyle(fontSize: 16)),
                        const SizedBox(height: 10),
                        Text('湿度:${_weatherResult!.realtime.humidity}%', style: const TextStyle(fontSize: 16)),
                        const SizedBox(height: 10),
                        Text('风向:${_weatherResult!.realtime.direct}', style: const TextStyle(fontSize: 16)),
                        const SizedBox(height: 10),
                        Text('风力:${_weatherResult!.realtime.power}级', style: const TextStyle(fontSize: 16)),
                      ],
                    ),
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

3.4 HarmonyOS适配配置

修改harmony/src/main/config.json文件,配置应用基本信息与设备支持类型,确保适配HarmonyOS设备:

复制代码
{
  "app": {
    "bundleName": "com.example.flutterharmonyweather",
    "vendor": "example",
    "version": {
      "code": 1000000,
      "name": "1.0.0"
    }
  },
  "module": {
    "package": "com.example.flutterharmonyweather",
    "name": ".MainApplication",
    "mainAbility": "com.example.flutterharmonyweather.MainAbility",
    "deviceType": ["phone"], // 支持手机设备
    "distro": {
      "deliveryWithInstall": true,
      "moduleName": "flutter_harmony_weather",
      "moduleType": "entry",
      "installationFree": false
    },
    "abilities": [
      {
        "name": "com.example.flutterharmonyweather.MainAbility",
        "label": "天气查询工具",
        "icon": "$media:icon",
        "description": "$string:mainability_description",
        "skills": [
          {
            "entities": ["entity.system.home"],
            "actions": ["action.system.home"]
          }
        ]
      }
    ]
  }
}

四、项目运行与调试

4.1 运行步骤

  1. 启动HarmonyOS模拟器:打开DevEco Studio的"Device Manager",选择Phone API 9模拟器并启动。

  2. 确认依赖已安装:终端执行flutter pub get,确保所有依赖加载完成。

  3. 选择运行设备:在DevEco Studio工具栏选择已启动的HarmonyOS模拟器。

  4. 启动项目:点击工具栏"运行"按钮(或快捷键Shift+F10),等待项目编译部署完成。

4.2 关键调试点

  1. API密钥问题:若出现"查询失败",优先检查API密钥是否正确、是否过期,可直接在浏览器访问API地址验证密钥有效性。

  2. 网络权限 :若出现网络请求失败,需确认HarmonyOS模拟器已连接网络,同时检查应用是否开启网络权限(DevEco Studio中可通过config.json添加网络权限配置)。

  3. JSON解析错误 :若出现解析异常,检查API返回数据格式是否与模型定义一致,可通过print(response.body)打印返回数据进行排查。

五、项目扩展方向

本项目为基础版本,可在此基础上扩展以下功能提升应用实用性,具体扩展方向、实现方式及核心价值如下表所示:

扩展功能 实现方式 核心价值
添加城市选择器 集成flutter_picker等第三方选择器插件,预设热门城市列表,替换原有输入框 降低用户输入成本,避免因城市名称输入错误导致的查询失败
新增未来几天天气预报 调用聚合数据天气API的多日预报接口,扩展WeatherModel数据模型,新增列表展示多日数据 丰富天气信息维度,满足用户对未来天气的查询需求
数据持久化 结合HarmonyOS的Preferences组件,封装数据存储工具类,保存历史查询记录 提升用户体验,用户下次打开应用可快速查看历史查询过的城市天气
主题切换 使用Flutter的Provider状态管理工具,定义浅色/深色主题配置,添加主题切换按钮控制状态 适配不同使用场景(如夜间使用),提升应用视觉舒适度

六、总结

本文通过"简易天气查询工具"项目,进一步演示了Flutter与DevEco Studio结合开发的实战流程,重点讲解了网络请求、JSON解析、HarmonyOS应用配置等核心知识点。相比上一个待办事项项目,本项目更贴近实际应用场景,涉及第三方API调用与数据处理,能帮助开发者更好地掌握跨平台技术与HarmonyOS生态的融合技巧。

开发过程中,需重点关注环境兼容性、API调用规范性及HarmonyOS配置正确性。若遇到问题,可结合IDE日志、官方文档及社区资源排查解决,逐步提升跨平台+HarmonyOS开发的实战能力。

欢迎大家加入[开源鸿蒙跨平台开发者社区](https://openharmonycrossplatform.csdn.net),一起共建开源鸿蒙跨平台生态。

相关推荐
小白|5 小时前
Flutter 与 OpenHarmony 深度融合:实现分布式文件共享与跨设备协同编辑系统
分布式·flutter·wpf
帅气马战的账号15 小时前
OpenHarmony与Flutter深度融合:分布式跨端开发全栈实践指南
flutter
遝靑5 小时前
Flutter 状态管理深度剖析:Provider/Bloc/GetX 原理 + 实战 + 选型(附避坑 & 性能对比)
flutter
豫狮恒5 小时前
OpenHarmony Flutter 分布式数据持久化:跨设备数据一致性与同步方案
分布式·安全·flutter·wpf·openharmony
ITKEY_5 小时前
flutter 运行windows版本报错
windows·flutter
狮恒5 小时前
OpenHarmony Flutter 分布式能力调度:跨设备服务协同与资源共享方案
分布式·flutter·wpf·openharmony
小白|5 小时前
Flutter 应用保活与后台任务:在 OpenHarmony 上实现定时上报
flutter
狮恒5 小时前
OpenHarmony Flutter 分布式音视频协同:跨设备实时流传输与同步渲染方案
分布式·flutter·wpf·音视频·openharmony
ujainu5 小时前
Flutter开发基石:Dart语言从入门到实战核心指南
flutter·dart