You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中freezed包的使用及Weather数据类转换方法

在Flutter中使用freezed包并改造Weather数据类

一、安装依赖

首先在pubspec.yaml中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  freezed_annotation: ^2.4.1
  json_annotation: ^4.9.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.4.9
  freezed: ^2.5.2
  json_serializable: ^6.8.0

执行命令安装依赖:

flutter pub get

二、生成代码

freezed依赖代码生成,执行以下命令生成所需文件:

flutter pub run build_runner build --delete-conflicting-outputs

三、改造Weather数据类

针对嵌套JSON(hourly/daily层级)和属性名与JSON字段不一致的问题,可按以下方式处理:

完整改造代码

import 'package:freezed_annotation/freezed_annotation.dart';

part 'weather.freezed.dart';
part 'weather.g.dart';

// 辅助转换函数:将num列表转为double列表
List<double> _numListToDoubleList(List<dynamic> list) {
  return list.map((e) => (e as num).toDouble()).toList();
}

// 辅助转换函数:将num列表转为int列表
List<int> _numListToIntList(List<dynamic> list) {
  return list.map((e) => (e as num).toInt()).toList();
}

@freezed
class Weather with _$Weather {
  const factory Weather({
    // Daily 层级属性
    @JsonKey(name: 'daily_time') required List<String> timeDaily,
    @JsonKey(name: 'daily_weathercode') required List<int> weatherCodesDaily,
    @JsonKey(name: 'daily_temp_min', fromJson: _numListToDoubleList) required List<double> minTemps,
    @JsonKey(name: 'daily_temp_max', fromJson: _numListToDoubleList) required List<double> maxTemps,
    @JsonKey(name: 'daily_sunrise') required List<String> sunriseList,
    @JsonKey(name: 'daily_sunset') required List<String> sunsetList,

    // Hourly 层级属性
    @JsonKey(name: 'hourly_time') required List<String> time,
    @JsonKey(name: 'hourly_weathercode') required List<int> weatherCodes,
    @JsonKey(name: 'hourly_temp', fromJson: _numListToDoubleList) required List<double> temperatures,
    @JsonKey(name: 'hourly_apparent_temp', fromJson: _numListToDoubleList) required List<double> feelsLikeTemps,
    @JsonKey(name: 'hourly_dewpoint', fromJson: _numListToDoubleList) required List<double> dewpoints,
    @JsonKey(name: 'hourly_visibility', fromJson: _numListToIntList) required List<int> visibility,
    @JsonKey(name: 'hourly_wind_dir', fromJson: _numListToIntList) required List<int> direction,
    @JsonKey(name: 'hourly_wind_speed', fromJson: _numListToDoubleList) required List<double> windSpeed,
    @JsonKey(name: 'hourly_wind_gust', fromJson: _numListToDoubleList) required List<double> windGust,
    @JsonKey(name: 'hourly_evapotranspiration', fromJson: _numListToDoubleList) required List<double> evapotranspiration,
    @JsonKey(name: 'hourly_precipitation', fromJson: _numListToDoubleList) required List<double> precipitation,
    @JsonKey(name: 'hourly_rain', fromJson: _numListToDoubleList) required List<double> rain,
    @JsonKey(name: 'hourly_humidity', fromJson: _numListToIntList) required List<int> humidity,
    @JsonKey(name: 'hourly_cloud_cover', fromJson: _numListToIntList) required List<int> cloudCover,
    @JsonKey(name: 'hourly_radiation', fromJson: _numListToDoubleList) required List<double> radiation,
  }) = _Weather;

  factory Weather.fromJson(Map<String, dynamic> json) {
    // 提取嵌套的daily和hourly对象
    final daily = json['daily'] as Map<String, dynamic>;
    final hourly = json['hourly'] as Map<String, dynamic>;

    // 合并嵌套字段到统一的map,避免字段名冲突
    final combinedJson = {
      // Daily 字段映射
      'daily_time': daily['time'],
      'daily_weathercode': daily['weathercode'],
      'daily_temp_min': daily['temperature_2m_min'],
      'daily_temp_max': daily['temperature_2m_max'],
      'daily_sunrise': daily['sunrise'],
      'daily_sunset': daily['sunset'],

      // Hourly 字段映射
      'hourly_time': hourly['time'],
      'hourly_weathercode': hourly['weathercode'],
      'hourly_temp': hourly['temperature_2m'],
      'hourly_apparent_temp': hourly['apparent_temperature'],
      'hourly_dewpoint': hourly['dewpoint_2m'],
      'hourly_visibility': hourly['visibility'],
      'hourly_wind_dir': hourly['winddirection_10m'],
      'hourly_wind_speed': hourly['windspeed_10m'],
      'hourly_wind_gust': hourly['windgusts_10m'],
      'hourly_evapotranspiration': hourly['evapotranspiration'],
      'hourly_precipitation': hourly['precipitation'],
      'hourly_rain': hourly['rain'],
      'hourly_humidity': hourly['relativehumidity_2m'],
      'hourly_cloud_cover': hourly['cloudcover'],
      'hourly_radiation': hourly['shortwave_radiation'],
    };

    // 交给自动生成的序列化函数处理
    return _$WeatherFromJson(combinedJson);
  }
}

关键说明

  1. 嵌套JSON处理:在fromJson工厂函数中,先从原JSON提取daily和hourly嵌套对象,再将它们的字段映射到自定义键(如daily_time、hourly_dewpoint),避免字段名冲突(比如daily和hourly都有time字段)。
  2. 属性名与JSON字段映射:通过@JsonKey(name: '自定义键')标注类属性,对应combinedJson中的键,实现类属性名与原始JSON字段名的映射(比如dewpoints对应hourly['dewpoint_2m'])。
  3. 类型转换:通过@JsonKey(fromJson: 转换函数)处理JSON中数值类型到目标类型的转换,比如将num列表转为double/int列表,和原代码的转换逻辑保持一致。
  4. freezed特性:自动生成不可变类、toString、equals、hashCode等方法,无需手动编写,减少样板代码。

内容的提问来源于stack exchange,提问作者Асыл Батыр

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:59:56