MoodCanvas/lib/providers/weather_provider.dart
fengshengxiong 91b7eebbf2 接入TopON
2026-01-22 16:34:55 +08:00

198 lines
5.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/weather.dart';
import '../services/weather_service.dart';
class WeatherProvider with ChangeNotifier {
final WeatherService _weatherService = WeatherService();
Weather? _currentWeather;
List<WeatherForecast> _forecast = [];
bool _isLoading = false;
String? _error;
String _selectedLocation = '';
List<String> _favoriteLocations = [];
// Getters
Weather? get currentWeather => _currentWeather;
List<WeatherForecast> get forecast => _forecast;
bool get isLoading => _isLoading;
String? get error => _error;
String get selectedLocation => _selectedLocation;
List<String> get favoriteLocations => _favoriteLocations;
WeatherProvider() {
_loadFavoriteLocations();
refreshWeather();
}
// 刷新天气数据
Future<void> refreshWeather({String? location}) async {
_setLoading(true);
_error = null;
try {
// 获取当前天气
final weather = await _weatherService.getCurrentWeather(
location: location,
);
if (weather != null) {
_currentWeather = weather;
_selectedLocation = weather.location;
// 获取预报
final forecastData = await _weatherService.getWeatherForecast(
location: location,
);
_forecast = forecastData;
// 保存最后选择的位置
await _saveLastLocation(_selectedLocation);
} else {
_error = 'Unable to get weather data, please check network connection';
}
} catch (e) {
_error = 'Failed to get weather data: $e';
} finally {
_setLoading(false);
}
}
// 根据城市名获取天气
Future<void> getWeatherByCity(String cityName) async {
await refreshWeather(location: cityName);
}
// 搜索城市
Future<List<Map<String, dynamic>>> searchCities(String query) async {
if (query.isEmpty) return [];
try {
return await _weatherService.searchLocations(query);
} catch (e) {
debugPrint('搜索城市失败: $e');
return [];
}
}
// 添加到收藏位置
Future<void> addToFavorites(String location) async {
if (!_favoriteLocations.contains(location)) {
_favoriteLocations.add(location);
await _saveFavoriteLocations();
notifyListeners();
}
}
// 从收藏位置移除
Future<void> removeFromFavorites(String location) async {
_favoriteLocations.remove(location);
await _saveFavoriteLocations();
notifyListeners();
}
// 检查是否为收藏位置
bool isFavorite(String location) {
return _favoriteLocations.contains(location);
}
// 获取收藏位置的天气
Future<List<Weather>> getFavoriteWeathers() async {
List<Weather> weathers = [];
for (String location in _favoriteLocations) {
try {
final weather = await _weatherService.getWeatherByCity(location);
if (weather != null) {
weathers.add(weather);
}
} catch (e) {
debugPrint('获取收藏位置天气失败: $location - $e');
}
}
return weathers;
}
// 设置加载状态
void _setLoading(bool loading) {
_isLoading = loading;
notifyListeners();
}
// 保存收藏位置
Future<void> _saveFavoriteLocations() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setStringList('favorite_locations', _favoriteLocations);
}
// 加载收藏位置
Future<void> _loadFavoriteLocations() async {
final prefs = await SharedPreferences.getInstance();
_favoriteLocations = prefs.getStringList('favorite_locations') ?? [];
notifyListeners();
}
// 保存最后选择的位置
Future<void> _saveLastLocation(String location) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('last_location', location);
}
// 清除错误
void clearError() {
_error = null;
notifyListeners();
}
// 获取天气图标对应的本地图标
IconData getWeatherIcon(String condition) {
final lowerCondition = condition.toLowerCase();
if (lowerCondition.contains('sunny') || lowerCondition.contains('clear')) {
return Icons.wb_sunny;
} else if (lowerCondition.contains('cloud')) {
return Icons.cloud;
} else if (lowerCondition.contains('rain') ||
lowerCondition.contains('drizzle')) {
return Icons.grain;
} else if (lowerCondition.contains('snow')) {
return Icons.ac_unit;
} else if (lowerCondition.contains('thunder') ||
lowerCondition.contains('storm')) {
return Icons.flash_on;
} else if (lowerCondition.contains('fog') ||
lowerCondition.contains('mist')) {
return Icons.blur_on;
} else if (lowerCondition.contains('wind')) {
return Icons.air;
} else {
return Icons.wb_cloudy;
}
}
// 获取天气颜色主题
Color getWeatherColor(String condition) {
final lowerCondition = condition.toLowerCase();
if (lowerCondition.contains('sunny') || lowerCondition.contains('clear')) {
return Colors.orange;
} else if (lowerCondition.contains('cloud')) {
return Colors.grey;
} else if (lowerCondition.contains('rain') ||
lowerCondition.contains('drizzle')) {
return Colors.blue;
} else if (lowerCondition.contains('snow')) {
return Colors.lightBlue;
} else if (lowerCondition.contains('thunder') ||
lowerCondition.contains('storm')) {
return Colors.purple;
} else if (lowerCondition.contains('fog') ||
lowerCondition.contains('mist')) {
return Colors.blueGrey;
} else {
return Colors.grey;
}
}
}