import 'package:common_utils/common_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; /// 构建天气内容卡片 Widget buildWeatherContent(BuildContext context, String city, Map now, List> days) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '查询天气情况:', style: TextStyle( color: isDarkMode ? Colors.white.withValues(alpha: 0.9) : Colors.black87, fontSize: 14.sp, height: 1.4, fontWeight: FontWeight.w400, ), ), SizedBox(height: 12.h), Container( padding: EdgeInsets.all(16.w), decoration: BoxDecoration( gradient: isDarkMode ? const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Color(0xFF1E40AF), Color(0xFF1E3A8A)], ) : const LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Color(0xFF60A5FA), Color(0xFF3B82F6)], ), borderRadius: BorderRadius.circular(12.r), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: isDarkMode ? 0.3 : 0.1), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "${city} ${now["date"]}", style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white, ), ), SizedBox(height: 4), Text( now["dayweather"], style: TextStyle( fontSize: 14.sp, color: Colors.white.withValues(alpha: 0.9), ), ), SizedBox(height: 8.h), Row( children: [ Text( "${now["daytemp"]}°", style: TextStyle( fontSize: 36.sp, fontWeight: FontWeight.bold, color: Colors.white, ), ), SizedBox(width: 8.w), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '最高: ${now["daytemp"]}°', style: TextStyle( fontSize: 12.sp, color: Colors.white.withValues(alpha: 0.9), ), ), Text( '最低: ${now["nighttemp"]}°', style: TextStyle( fontSize: 12.sp, color: Colors.white.withValues(alpha: 0.9), ), ), ], ), ], ), ], ), Icon( getWeatherIcon(now['dayweather']), size: 48.sp, color: Colors.white, ), ], ), SizedBox(height: 16.h), Container( height: 1, color: Colors.white.withValues(alpha: isDarkMode ? 0.15 : 0.2), ), SizedBox(height: 16.h), Text( '未来预报', style: TextStyle( fontSize: 14.sp, fontWeight: FontWeight.w600, color: Colors.white, ), ), SizedBox(height: 8.h), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: List.generate( days.length, (index) { String dateStr = days[index]['date']; DateTime? date = DateUtil.getDateTime(dateStr); IconData weatherIcon = getWeatherIcon(days[index]['dayweather']); String weekday = DateUtil.getWeekday(date, languageCode: "zh", short: true); String temp = "${days[index]['daytemp']}°"; return _buildForecastDay( weekday, weatherIcon, temp, ); }, ), ), SizedBox(height: 16.h), _buildWeatherTip(context, now, isDarkMode), ], ), ), ], ); } /// 构建智能天气提示 Widget _buildWeatherTip(BuildContext context, Map now, bool isDarkMode) { final weatherTip = _generateWeatherTip(now); return Container( padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 12.w), decoration: BoxDecoration( color: isDarkMode ? Colors.white.withValues(alpha: 0.15) : Colors.white.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(8.r), ), child: Row( children: [ Icon( weatherTip.icon, size: 16.sp, color: Colors.white, ), SizedBox(width: 8.w), Flexible( child: Text( weatherTip.message, style: TextStyle( fontSize: 12.sp, color: Colors.white, ), ), ), ], ), ); } /// 天气提示数据类 class WeatherTip { final IconData icon; final String message; const WeatherTip({required this.icon, required this.message}); } /// 根据天气数据生成智能提示 WeatherTip _generateWeatherTip(Map now) { final dayWeather = (now['dayweather'] as String? ?? '').trim(); final dayTemp = int.tryParse(now['daytemp']?.toString() ?? '0') ?? 0; final nightTemp = int.tryParse(now['nighttemp']?.toString() ?? '0') ?? 0; // 高温提示 (>= 35°C) if (dayTemp >= 35) { return const WeatherTip( icon: Icons.local_fire_department, message: '今日高温炎热,请注意防暑降温,多喝水避免中暑', ); } // 低温提示 (<= 5°C) if (dayTemp <= 5) { return const WeatherTip( icon: Icons.ac_unit, message: '今日气温较低,外出请注意保暖,小心感冒', ); } // 雨天提示 if (dayWeather.contains('雨') || ['阵雨', '雷阵雨', '小雨', '中雨', '大雨', '暴雨'].any((rain) => dayWeather.contains(rain))) { return const WeatherTip( icon: Icons.umbrella, message: '今日有雨,外出请携带雨具,注意出行安全', ); } // 雪天提示 if (dayWeather.contains('雪') || ['阵雪', '小雪', '中雪', '大雪', '暴雪'].any((snow) => dayWeather.contains(snow))) { return const WeatherTip( icon: Icons.ac_unit, message: '今日有雪,路面湿滑请注意安全,做好保暖措施', ); } // 雾霾提示 if (dayWeather.contains('雾') || dayWeather.contains('霾') || ['雾', '浓雾', '霾', '中度霾', '重度霾'].any((fog) => dayWeather.contains(fog))) { return const WeatherTip( icon: Icons.blur_on, message: '今日有雾霾,能见度较低,外出请佩戴口罩', ); } // 大风提示 if (dayWeather.contains('风') || ['大风', '强风', '疾风', '烈风'].any((wind) => dayWeather.contains(wind))) { return const WeatherTip( icon: Icons.air, message: '今日风力较大,外出请注意安全,固定好物品', ); } // 晴天紫外线提示 (温度 >= 25°C) if (['晴', '少云', '晴间多云'].any((sunny) => dayWeather.contains(sunny)) && dayTemp >= 25) { return const WeatherTip( icon: Icons.wb_sunny, message: '今日阳光充足紫外线较强,外出请做好防晒', ); } // 温差大提示 (>= 10°C) if ((dayTemp - nightTemp).abs() >= 10) { return const WeatherTip( icon: Icons.thermostat, message: '今日昼夜温差较大,请适时增减衣物', ); } // 默认舒适天气提示 return const WeatherTip( icon: Icons.wb_sunny_outlined, message: '今日天气适宜,是外出活动的好时光', ); } /// 构建单日天气预报 Widget _buildForecastDay(String day, IconData icon, String temp) { return Column( children: [ Text( day, style: TextStyle( fontSize: 12.sp, color: Colors.white.withValues(alpha: 0.9), ), ), SizedBox(height: 4.h), Icon( icon, size: 20.sp, color: Colors.white, ), SizedBox(height: 4.h), Text( temp, style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w500, color: Colors.white, ), ), ], ); } /// 获取天气图标 IconData getWeatherIcon(String description) { description = description.trim(); if (["晴", "少云", "晴间多云"].contains(description)) { return Icons.wb_sunny; } if (["多云", "阴"].contains(description)) { return Icons.cloud; } if (description.contains("雾") || ["雾", "浓雾", "强浓雾", "轻雾", "大雾", "特强浓雾", "霾", "中度霾", "重度霾", "严重霾"] .contains(description)) { return Icons.blur_on; } if (description.contains("风") || [ "有风", "平静", "微风", "和风", "清风", "强风/劲风", "疾风", "大风", "烈风", "风暴", "狂爆风", "飓风", "热带风暴" ].contains(description)) { return Icons.air; } if (description.contains("雨") || [ "阵雨", "雷阵雨", "雷阵雨并伴有冰雹", "小雨", "中雨", "大雨", "暴雨", "大暴雨", "特大暴雨", "强阵雨", "强雷阵雨", "极端降雨", "毛毛雨/细雨", "雨", "小雨-中雨", "中雨-大雨", "大雨-暴雨", "暴雨-大暴雨", "大暴雨-特大暴雨" ].contains(description)) { return Icons.grain; // 或使用 community icon 包:weather_icons 中的 rain } if (description.contains("雪") || [ "雨雪天气", "雨夹雪", "阵雨夹雪", "冻雨", "雪", "阵雪", "小雪", "中雪", "大雪", "暴雪", "小雪-中雪", "中雪-大雪", "大雪-暴雪" ].contains(description)) { return Icons.ac_unit; } if (["浮尘", "扬沙", "沙尘暴", "强沙尘暴"].contains(description)) { return Icons.filter_drama; } if (["龙卷风"].contains(description)) { return Icons.waves; } if (["热"].contains(description)) { return Icons.local_fire_department; } if (["冷"].contains(description)) { return Icons.ac_unit; } // 默认或未知天气 return Icons.help_outline; }