Flutter & OpenHarmony 运动App运动天气服务组件开发

前言

天气信息对户外运动至关重要,温度、湿度、风速等因素直接影响运动体验和安全。本文将详细介绍如何在Flutter与OpenHarmony平台上实现运动天气服务组件,包括天气获取、运动建议、恶劣天气预警等功能模块的完整实现方案。

Flutter天气数据模型

dart 复制代码
class WeatherData {
  final double temperature;
  final double feelsLike;
  final int humidity;
  final double windSpeed;
  final String condition;
  final String icon;
  final int uvIndex;
  final double visibility;
  
  WeatherData({
    required this.temperature,
    required this.feelsLike,
    required this.humidity,
    required this.windSpeed,
    required this.condition,
    required this.icon,
    required this.uvIndex,
    required this.visibility,
  });
  
  String get runningAdvice {
    if (temperature < 0) return '气温过低,建议室内运动';
    if (temperature > 35) return '高温预警,避免户外运动';
    if (humidity > 85) return '湿度较高,注意补水';
    if (windSpeed > 10) return '风力较大,注意安全';
    if (uvIndex > 7) return '紫外线强,注意防晒';
    if (temperature >= 15 && temperature <= 25) return '适宜跑步的好天气';
    return '可以进行户外运动';
  }
  
  Color get adviceColor {
    if (temperature < 0 || temperature > 35 || windSpeed > 10) return Colors.red;
    if (humidity > 85 || uvIndex > 7) return Colors.orange;
    return Colors.green;
  }
}

天气数据模型包含运动相关的关键气象指标。temperature和feelsLike分别是实际温度和体感温度,humidity是湿度百分比,windSpeed是风速。runningAdvice属性根据各项指标生成运动建议,考虑了极端温度、高湿度、大风和强紫外线等不利因素。adviceColor根据建议的严重程度返回对应颜色,红色表示不建议运动,绿色表示适宜运动。

OpenHarmony天气获取服务

typescript 复制代码
import http from '@ohos.net.http';
import geoLocationManager from '@ohos.geoLocationManager';

class WeatherService {
  private apiKey: string = 'your_api_key';
  
  async getCurrentWeather(): Promise<object | null> {
    try {
      let location = await this.getCurrentLocation();
      if (!location) return null;
      
      let httpRequest = http.createHttp();
      let response = await httpRequest.request(
        `https://api.weather.com/v1/current?lat=${location.latitude}&lon=${location.longitude}&key=${this.apiKey}`,
        { method: http.RequestMethod.GET }
      );
      
      httpRequest.destroy();
      
      if (response.responseCode === 200) {
        return JSON.parse(response.result as string);
      }
      return null;
    } catch (error) {
      console.error('获取天气失败: ' + error);
      return null;
    }
  }
  
  private async getCurrentLocation(): Promise<object | null> {
    try {
      let location = await geoLocationManager.getCurrentLocation({
        priority: geoLocationManager.LocationRequestPriority.ACCURACY,
        scenario: geoLocationManager.LocationRequestScenario.UNSET,
        maxAccuracy: 100,
        timeoutMs: 10000,
      });
      return { latitude: location.latitude, longitude: location.longitude };
    } catch (error) {
      return null;
    }
  }
  
  async getHourlyForecast(): Promise<Array<object>> {
    // 获取逐小时预报
    return [];
  }
}

天气获取服务结合定位和天气API获取当前位置的天气数据。getCurrentLocation方法获取用户当前位置的经纬度,getCurrentWeather方法使用位置信息调用天气API。这种基于位置的天气服务确保用户获得准确的本地天气信息。getHourlyForecast方法可以获取未来几小时的天气预报,帮助用户规划运动时间。

Flutter天气卡片组件

dart 复制代码
class WeatherCard extends StatelessWidget {
  final WeatherData weather;
  
  const WeatherCard({Key? key, required this.weather}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.all(16),
      child: Padding(
        padding: EdgeInsets.all(16),
        child: Column(
          children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('${weather.temperature.toInt()}°', style: TextStyle(fontSize: 48, fontWeight: FontWeight.bold)),
                    Text('体感 ${weather.feelsLike.toInt()}°', style: TextStyle(color: Colors.grey)),
                  ],
                ),
                Column(
                  children: [
                    Text(weather.icon, style: TextStyle(fontSize: 48)),
                    Text(weather.condition),
                  ],
                ),
              ],
            ),
            SizedBox(height: 16),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: [
                _buildInfoItem(Icons.water_drop, '${weather.humidity}%', '湿度'),
                _buildInfoItem(Icons.air, '${weather.windSpeed.toInt()}m/s', '风速'),
                _buildInfoItem(Icons.wb_sunny, '${weather.uvIndex}', 'UV'),
              ],
            ),
            SizedBox(height: 16),
            Container(
              padding: EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: weather.adviceColor.withOpacity(0.1),
                borderRadius: BorderRadius.circular(8),
              ),
              child: Row(
                children: [
                  Icon(Icons.directions_run, color: weather.adviceColor),
                  SizedBox(width: 8),
                  Expanded(child: Text(weather.runningAdvice, style: TextStyle(color: weather.adviceColor))),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
  
  Widget _buildInfoItem(IconData icon, String value, String label) {
    return Column(
      children: [
        Icon(icon, color: Colors.grey),
        SizedBox(height: 4),
        Text(value, style: TextStyle(fontWeight: FontWeight.bold)),
        Text(label, style: TextStyle(fontSize: 12, color: Colors.grey)),
      ],
    );
  }
}

天气卡片组件展示当前天气和运动建议。左侧显示温度和体感温度,右侧显示天气图标和状况描述。中间行显示湿度、风速和紫外线指数三个关键指标。底部的建议区域根据天气条件给出运动建议,使用颜色区分建议的紧急程度。这种设计让用户一眼就能了解当前天气是否适合户外运动。

OpenHarmony天气预警服务

typescript 复制代码
import notificationManager from '@ohos.notificationManager';

class WeatherAlertService {
  async checkAndAlert(weather: object): Promise<void> {
    let alerts: Array<string> = [];
    
    if (weather['temperature'] > 35) {
      alerts.push('高温预警:当前气温超过35°C,不建议户外运动');
    }
    if (weather['temperature'] < 0) {
      alerts.push('低温预警:当前气温低于0°C,注意保暖');
    }
    if (weather['windSpeed'] > 10) {
      alerts.push('大风预警:当前风速较大,户外运动请注意安全');
    }
    if (weather['uvIndex'] > 8) {
      alerts.push('紫外线预警:UV指数过高,请做好防晒措施');
    }
    
    for (let alert of alerts) {
      await this.sendAlert(alert);
    }
  }
  
  private async sendAlert(message: string): Promise<void> {
    let notificationRequest: notificationManager.NotificationRequest = {
      id: Date.now(),
      content: {
        notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
        normal: {
          title: '⚠️ 天气预警',
          text: message,
        }
      }
    };
    
    await notificationManager.publish(notificationRequest);
  }
}

天气预警服务在检测到不利天气条件时发送通知。checkAndAlert方法检查多项天气指标,包括高温、低温、大风和强紫外线。每个预警条件触发时发送对应的通知消息。这种主动预警机制帮助用户避免在恶劣天气下运动,保障运动安全。

Flutter天气时间线组件

dart 复制代码
class WeatherTimeline extends StatelessWidget {
  final List<HourlyWeather> hourlyData;
  
  const WeatherTimeline({Key? key, required this.hourlyData}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: EdgeInsets.symmetric(horizontal: 16),
          child: Text('逐小时预报', style: TextStyle(fontWeight: FontWeight.bold)),
        ),
        SizedBox(height: 8),
        SizedBox(
          height: 100,
          child: ListView.builder(
            scrollDirection: Axis.horizontal,
            padding: EdgeInsets.symmetric(horizontal: 16),
            itemCount: hourlyData.length,
            itemBuilder: (context, index) {
              var hour = hourlyData[index];
              bool isBestTime = hour.temperature >= 15 && hour.temperature <= 25 && hour.humidity < 80;
              
              return Container(
                width: 60,
                margin: EdgeInsets.only(right: 8),
                padding: EdgeInsets.all(8),
                decoration: BoxDecoration(
                  color: isBestTime ? Colors.green.withOpacity(0.1) : Colors.grey[100],
                  borderRadius: BorderRadius.circular(12),
                  border: isBestTime ? Border.all(color: Colors.green) : null,
                ),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(hour.time, style: TextStyle(fontSize: 12)),
                    SizedBox(height: 4),
                    Text(hour.icon, style: TextStyle(fontSize: 20)),
                    SizedBox(height: 4),
                    Text('${hour.temperature.toInt()}°', style: TextStyle(fontWeight: FontWeight.bold)),
                  ],
                ),
              );
            },
          ),
        ),
      ],
    );
  }
}

class HourlyWeather {
  final String time;
  final double temperature;
  final int humidity;
  final String icon;
  
  HourlyWeather({required this.time, required this.temperature, required this.humidity, required this.icon});
}

天气时间线组件展示未来几小时的天气变化。横向滚动列表显示每小时的时间、天气图标和温度。适宜运动的时段使用绿色边框高亮显示,帮助用户选择最佳运动时间。这种可视化的时间线让用户可以规划一天中的运动安排,避开不利天气时段。

总结

本文全面介绍了Flutter与OpenHarmony平台上运动天气服务组件的实现方案。从天气数据获取到运动建议生成,从天气展示到���警通知,涵盖了天气服务的各个方面。通过准确的天气信息和智能的运动建议,我们可以帮助用户选择最佳运动时机,保障户外运动的安全和体验。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

相关推荐
程序员Ctrl喵17 小时前
异步编程:Event Loop 与 Isolate 的深层博弈
开发语言·flutter
前端不太难18 小时前
Flutter 如何设计可长期维护的模块边界?
flutter
小蜜蜂嗡嗡19 小时前
flutter列表中实现置顶动画
flutter
始持20 小时前
第十二讲 风格与主题统一
前端·flutter
始持20 小时前
第十一讲 界面导航与路由管理
flutter·vibecoding
始持20 小时前
第十三讲 异步操作与异步构建
前端·flutter
新镜20 小时前
【Flutter】 视频视频源横向、竖向问题
flutter
黄林晴21 小时前
Compose Multiplatform 1.10 发布:统一 Preview、Navigation 3、Hot Reload 三箭齐发
android·flutter
Swift社区21 小时前
Flutter 应该按功能拆,还是按技术层拆?
flutter
肠胃炎1 天前
树形选择器组件封装
前端·flutter