ArkUI 天气预报 App:HTTP 请求 + 定位 + 动效)
️ 鸿蒙原生应用实战九ArkUI 天气预报 AppHTTP 请求 定位 动效博主说天气预报是每个手机的基础应用也是学习「网络请求 定位 动画」全链路的最佳项目。今天我们用 ArkUI 的 HTTP 网络请求 地理定位 API从零实现一个支持自动定位、未来 7 天预报、天气动效的完整天气 App。 应用场景功能说明 自动定位获取当前位置并显示天气️ 实时温度当前温度 体感温度 7天预报未来 7 天的天气概况 天气动效晴天/阴天/雨天/雪天动态背景 城市搜索手动切换城市️ 天气详情湿度/风速/紫外线/空气质量⚙️ 运行环境要求项目版本要求DevEco Studio5.0.3.800HarmonyOS SDKAPI 12核心 APIohos.net.httpohos.geoLocation权限INTERNET LOCATION️ 实战从零搭建天气预报 AppStep 1天气数据模型interfaceWeatherData{city:string;temperature:number;// 当前温度feelsLike:number;// 体感温度condition:string;// 天气状况 (晴/多云/雨等)humidity:number;// 湿度 %windSpeed:number;// 风速uvIndex:number;// 紫外线aqi:number;// 空气质量指数forecast:DayForecast[];// 7天预报}interfaceDayForecast{date:string;high:number;low:number;condition:string;icon:string;}Step 2完整代码// pages/Index.ets — 天气预报importhttpfromohos.net.http;importgeoLocationfromohos.geoLocation;importabilityAccessCtrlfromohos.abilityAccessCtrl;EntryComponentstruct WeatherApp{Stateweather:WeatherData|nullnull;StateisLoading:booleantrue;StatecityName:string北京;StatecurrentPage:number0;// 0今天, 17天StatelocationEnabled:booleanfalse;// 天气动画状态StateanimationType:sunny|cloudy|rainy|snowysunny;aboutToAppear(){this.requestLocation();}asyncrequestLocation(){try{constatManagerabilityAccessCtrl.createAtManager();awaitatManager.requestPermissionsFromUser(getContext(this),[ohos.permission.LOCATION]);this.locationEnabledtrue;constlocawaitgeoLocation.getCurrentLocation({priority:geoLocation.LocationRequestPriority.FIRST_FIX,timeoutMs:5000});// 用经纬度获取城市名this.fetchWeatherByCoords(loc.latitude,loc.longitude);}catch{// 定位失败用默认城市this.fetchWeatherByCity(北京);}}asyncfetchWeatherByCoords(lat:number,lon:number){this.isLoadingtrue;try{constreqhttp.createHttp();constrespawaitreq.request(https://api.openweathermap.org/data/2.5/weather?lat${lat}lon${lon}appidYOUR_API_KEYunitsmetriclangzh_cn,{method:http.RequestMethod.GET,expectDataType:http.HttpDataType.OBJECT});constdataJSON.parse(resp.resultasstring);this.cityNamedata.name;this.parseWeatherData(data);}catch{this.fetchWeatherByCity(北京);}this.isLoadingfalse;}asyncfetchWeatherByCity(city:string){this.isLoadingtrue;try{constreqhttp.createHttp();constrespawaitreq.request(https://api.openweathermap.org/data/2.5/weather?q${city}appidYOUR_API_KEYunitsmetriclangzh_cn,{method:http.RequestMethod.GET,expectDataType:http.HttpDataType.OBJECT});constdataJSON.parse(resp.resultasstring);this.parseWeatherData(data);// 同时获取7天预报constresp2awaitreq.request(https://api.openweathermap.org/data/2.5/forecast?q${city}appidYOUR_API_KEYunitsmetriclangzh_cn,{method:http.RequestMethod.GET});constforecastDataJSON.parse(resp2.resultasstring);this.parseForecast(forecastData);}catch(err){AlertDialog.show({message:获取天气数据失败请检查网络});}this.isLoadingfalse;}parseWeatherData(data:any){this.weather{city:data.name,temperature:Math.round(data.main.temp),feelsLike:Math.round(data.main.feels_like),condition:data.weather[0].description,humidity:data.main.humidity,windSpeed:data.wind.speed,uvIndex:0,aqi:0,forecast:[]};this.updateAnimation(data.weather[0].main);}parseForecast(data:any){if(!this.weather)return;constdaily:DayForecast[][];constgroups:Recordstring,any[]{};for(constitemofdata.list){constdateitem.dt_txt.split( )[0];if(!groups[date])groups[date][];groups[date].push(item);}letcount0;for(constdateofObject.keys(groups)){if(count7)break;constitemsgroups[date];consthighsitems.map((i:any)i.main.temp_max);constlowsitems.map((i:any)i.main.temp_min);daily.push({date:date,high:Math.round(Math.max(...highs)),low:Math.round(Math.min(...lows)),condition:items[4]?.weather[0]?.description||items[0].weather[0].description,icon:items[0].weather[0].icon});count;}this.weather.forecastdaily;}updateAnimation(condition:string){if(condition.includes(Rain)||condition.includes(Drizzle)){this.animationTyperainy;}elseif(condition.includes(Snow)){this.animationTypesnowy;}elseif(condition.includes(Cloud)){this.animationTypecloudy;}else{this.animationTypesunny;}}getWeatherIcon():string{consticons:Recordstring,string{sunny:☀️,cloudy:⛅,rainy:️,snowy:❄️};returnicons[this.animationType]||☀️;}build(){Stack(){// ---- 天气动效背景 ----Column().width(100%).height(100%).backgroundColor(this.animationTypesunny?#4A90D9:this.animationTypecloudy?#8E9EAB:this.animationTyperainy?#4A5568:#B8C6D0)// ---- 主内容 ----if(this.isLoading){Column(){LoadingProgress().width(48).height(48).color(#fff)Text(获取天气数据...).fontSize(16).fontColor(#fff).margin({top:16})}}elseif(this.weather){Column(){// 城市 刷新Row(){Text(this.weather.city).fontSize(20).fontWeight(FontWeight.Bold).fontColor(#fff)Text(↻).fontSize(18).fontColor(rgba(255,255,255,0.7)).margin({left:8}).onClick((){this.fetchWeatherByCity(this.cityName);})}.padding({top:40})// 温度Text(this.getWeatherIcon()).fontSize(64).margin({top:8})Text(${this.weather.temperature}°C).fontSize(64).fontWeight(FontWeight.Bold).fontColor(#fff).margin({top:4})Text(this.weather.condition).fontSize(18).fontColor(rgba(255,255,255,0.8))Text(体感${this.weather.feelsLike}°C).fontSize(14).fontColor(rgba(255,255,255,0.6)).margin({top:4})// 详情卡片Row(){WeatherDetail(,湿度,${this.weather.humidity}%)WeatherDetail(,风速,${this.weather.windSpeed}m/s)WeatherDetail(☀️,紫外线,${this.weather.uvIndex})WeatherDetail(️,AQI,${this.weather.aqi})}.width(94%).padding(16).backgroundColor(rgba(255,255,255,0.2)).borderRadius(16).margin({top:16})// 7天预报if(this.weather.forecast.length0){Text( 未来 7 天).fontSize(16).fontWeight(FontWeight.Bold).fontColor(#fff).margin({top:16,bottom:8})List(){ForEach(this.weather.forecast,(day:DayForecast){ListItem(){Row(){Text(day.date.substring(5)).fontSize(14).fontColor(#fff).width(50)Text(this.getConditionEmoji(day.condition)).fontSize(20).width(30)Text(day.condition).fontSize(13).fontColor(rgba(255,255,255,0.7)).layoutWeight(1)Text(${day.low}°).fontSize(14).fontColor(rgba(255,255,255,0.6))Text(${day.high}°).fontSize(14).fontColor(#fff).fontWeight(FontWeight.Bold).width(40)}.padding(10).width(94%).backgroundColor(rgba(255,255,255,0.1)).borderRadius(8).margin({top:4})}},(day:DayForecast)day.date)}.height(200)}}.width(100%).height(100%).alignItems(HorizontalAlign.Center).justifyContent(FlexAlign.Start)}}.width(100%).height(100%)}getConditionEmoji(condition:string):string{if(condition.includes(晴))return☀️;if(condition.includes(云)||condition.includes(阴))return☁️;if(condition.includes(雨))return️;if(condition.includes(雪))return❄️;return️;}}BuilderfunctionWeatherDetail(icon:string,label:string,value:string){Column(){Text(icon).fontSize(24)Text(label).fontSize(12).fontColor(rgba(255,255,255,0.7)).margin({top:4})Text(value).fontSize(16).fontColor(#fff).fontWeight(FontWeight.Bold).margin({top:2})}}官方文档HarmonyOS 应用开发文档开发者社区华为开发者论坛欢迎加入开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.net/