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); } }
关键说明
- 嵌套JSON处理:在
fromJson工厂函数中,先从原JSON提取daily和hourly嵌套对象,再将它们的字段映射到自定义键(如daily_time、hourly_dewpoint),避免字段名冲突(比如daily和hourly都有time字段)。 - 属性名与JSON字段映射:通过
@JsonKey(name: '自定义键')标注类属性,对应combinedJson中的键,实现类属性名与原始JSON字段名的映射(比如dewpoints对应hourly['dewpoint_2m'])。 - 类型转换:通过
@JsonKey(fromJson: 转换函数)处理JSON中数值类型到目标类型的转换,比如将num列表转为double/int列表,和原代码的转换逻辑保持一致。 - freezed特性:自动生成不可变类、toString、equals、hashCode等方法,无需手动编写,减少样板代码。
内容的提问来源于stack exchange,提问作者Асыл Батыр
相关产品推荐
相关产品推荐

