kotlin 编写一个简单的天气预报app(五)增加forcast接口并显示

参考资料

OpenWeatherMap提供了一个/forecast接口,用于获取未来几天的天气预报。你可以使用HTTP GET请求访问该接口,并根据你所在的城市或地理坐标获取相应的天气数据。

以下是一个示例请求的URL和一些常用的参数:

URL: http://api.openweathermap.org/data/2.5/forecast

查询参数:

  • q (必需): 城市名称 (e.g. “London,uk”) 或城市ID (可在OpenWeatherMap网站上获得) 或地理坐标 (使用纬度和经度, e.g. “37.7749,-122.4194”)。
  • appid (必需): 你的OpenWeatherMap API密钥。
    可选参数:
    units: 温度单位 (例如 “metric” 表示摄氏度, “imperial” 表示华氏度)。
    lang: 返回的天气描述语言 (例如 “en” 表示英语)。

从openWeatherMap获取forecast

1.在WeatherService接口中增加请求函数。

getForecastByCityName:此方法与 getWeatherByCityName 方法类似,但它检索预报数据而不是当前天气数据。它还采用城市名称和 API 密钥作为参数,并返回 ForecastResponse 类型的 Call 对象,这是从 API 收到的响应。

interface WeatherService {@GET("weather")fun getWeatherByCityName(@Query("q") cityName : String,@Query("appid") apiKey : String) : Call<WeatherResponse>@GET("forecast")fun getForecastByCityName(@Query("q") cityName : String,@Query("appid") apiKey : String) : Call<ForecastResponse>
}

2.编译一个新的ForecastResponse 类,用于解析天气预报的 JSON 数据。它具有以下属性:

  • cod:表示响应 JSON 中的 cod 值的字符串变量。
  • message:表示响应 JSON 中的消息值的整数变量。
  • cnt:表示响应 JSON 中的 cnt 值的整数变量。
  • forecastCellList:ForecastCell 对象的ArrayList,表示响应JSON 中的预测单元格列表。
  • forecastCity:ForecastCity 对象,表示响应 JSON 中的城市详细信息。
    这些属性使用 @SerializedName 进行注释,以指定 JSON 中相应的键。提供默认值是为了初始化目的。
package com.example.myweather.openWeatherMapimport com.example.myweather.WeatherResponseClouds
import com.example.myweather.WeatherResponseCoord
import com.example.myweather.WeatherResponseWeather
import com.google.gson.annotations.SerializedNamedata class ForecastResponse (@SerializedName("cod")var cod: String = "",@SerializedName("message")var message: Int = 0,@SerializedName("cnt")var cnt : Int = 0,@SerializedName("list")var forecastCellList : ArrayList<ForecastCell>? = null,@SerializedName("city")var forecastCity: ForecastCity? = null
)data class ForecastCell (@SerializedName("dt")val dt: Long,@SerializedName("main")val main: ForecastMain,@SerializedName("weather")val weather: List<WeatherResponseWeather>,@SerializedName("clouds")val clouds: WeatherResponseClouds,@SerializedName("wind")val wind: ForecastWind,@SerializedName("visibility")val visibility: Int = 0,@SerializedName("pop")val pop: Double = 0.0,@SerializedName("rain")val rain: ForecastRain,@SerializedName("snow")val snow: ForecastSnow,@SerializedName("sys")val sys: ForecastSys,@SerializedName("dt_txt")val dt_txt: String = ""
)data class ForecastCity(@SerializedName("id")val id: Int = 0,@SerializedName("name")val name: String = "",@SerializedName("coord")val coord: WeatherResponseCoord,@SerializedName("country")val country: String ="",@SerializedName("population")val population:Int = 0,@SerializedName("timezone")val timezone: Int = 0,@SerializedName("sunrise")val sunrise: Int = 0,@SerializedName("sunset")val sunset: Int = 0
)data class ForecastMain(@SerializedName("temp")val temperature: Double = 0.0,@SerializedName("feels_like")val feelsLike: Double = 0.0,@SerializedName("temp_min")val minTemperature: Double = 0.0,@SerializedName("temp_max")val maxTemperature: Double = 0.0,@SerializedName("pressure")val pressure: Int = 0,@SerializedName("sea_level")val seaLevel: Int = 0,@SerializedName("grnd_level")val groundLevel: Int = 0,@SerializedName("humidity")val humidity: Int = 0,@SerializedName("temp_kf")val temperatureKf: Double = 0.0
)data class ForecastWind(@SerializedName("speed")val speed: Double = 0.0,@SerializedName("deg")val degree: Int = 0,@SerializedName("gust")val gust : Double = 0.0
)data class ForecastRain(@SerializedName("3h")val heightInThreeHours: Double = 0.0
)data class ForecastSnow(@SerializedName("3h")val heightInThreeHours: Double = 0.0
)data class ForecastSys(@SerializedName("pod")val partOfDay: String = ""
)

3.在CustomEvent.kt中增加ForecastResponseEvent事件

class ForecastResponseEvent(val forecastResponse: ForecastResponse)

4.在RetrofitClient.kt中增加getForecastByCityName函数,用来MainActivity中调用请求接口:

    fun getForecastByCityName(cityName: String) {val call = weatherService.getForecastByCityName(cityName, API_KEY)call.enqueue(object : Callback<ForecastResponse> {override fun onResponse(call : Call<ForecastResponse>,response: Response<ForecastResponse>) {if(response.isSuccessful) {val forecastData = response.body()handleForecastData(forecastData)} else {handleForecastFailure(response.message())}}override fun onFailure(call: Call<ForecastResponse>, t: Throwable) {handleForecastFailure(t.message!!)}})

5.并且增加了相应函数

  • handleForecastFailure接受消息字符串作为参数并将其与前缀一起打印出来。
  • handleForecastData接受一个ForecastResponse对象作为参数。它检查该对象是否为空,如果不为空,则创建一个对象ForecastResponseEvent并使用 EventBus 发布它。然后它调用该printForecastResponse函数并传入该ForecastResponse对象。
  • printForecastResponse接受一个ForecastResponse对象作为参数,并打印出该对象的各种属性,例如 、cod、message和cnt的大小forecastCellList。它还打印出对象的id和属性。nameforecastCity
    private fun handleForecastFailure(message: String) {println("handleForecastFailure:${message}")}private fun handleForecastData(forecastData: ForecastResponse?) {if(forecastData == null) returnval forecastResponseEvent = ForecastResponseEvent(forecastData)EventBus.getDefault().post(forecastResponseEvent)		//这里发送了forecastResponseEventprintForecastResponse(forecastData)}private  fun printForecastResponse(forecastResponse: ForecastResponse) {println("cod:${forecastResponse.cod}")println("message:${forecastResponse.message}")println("cnt:${forecastResponse.cnt}")println("list:${forecastResponse.forecastCellList?.size}")println("city id:${forecastResponse.forecastCity?.id} name:${forecastResponse.forecastCity?.name}")}

6.在MainActivity中,处理forecastResponseEvent事件:

该函数是一个事件处理程序,在收到onReceiveForecastResponsea 时调用。ForecastResponseEvent它采用事件对象作为参数,其中包含预测响应数据。该函数调用该updateForecastList函数根据接收到的数据更新预测列表。

updateForecastList函数接受一个ForecastResponse对象作为参数。然后,它创建一个SimpleDateFormat对象来格式化预测响应中的日期和时间。该函数初始化一个空的可变列表data来存储格式化的预测数据。

然后,该函数会迭代 的预测单元格列表中的每个单元格forecastResponse。对于每个单元格,它都会创建一个字符串,oneLine其中包含格式化的日期和时间、温度、feel_like、天气主体和天气描述。通过减去常数值并将其转换为整数,将温度从开尔文转换为摄氏度kelvins。

每个oneLine字符串都会添加到data列表中。

最后,该函数创建一个ArrayAdapter以data列表为数据源的适配器,并将其设置为ListViewID 的适配器listViewTodayForcast。这将使用更新的预测数据更新列表视图。

    @RequiresApi(Build.VERSION_CODES.O)@Subscribe(threadMode = ThreadMode.MAIN)fun onReceiveForecastResponse(event: ForecastResponseEvent) {updateForecastList(event.forecastResponse)}private fun updateForecastList(forecastResponse: ForecastResponse) {val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH)val data = mutableListOf<String>()for (cell in forecastResponse.forecastCellList!!) {val oneLine = "${simpleDateFormat.format(cell.dt*1000L)}\n" +"temperature:${cell.main.temperature.minus(kelvins).toInt()}," +"feel_like:${cell.main.feelsLike.minus(kelvins).toInt()},\n" +"weather:${cell.weather.first().main},${cell.weather.first().description}"data.add(oneLine)}val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data)findViewById<ListView>(R.id.listViewTodayForcast).adapter = adapter}

7.我在主界面中增加了一个ListView用来显示forecast返回的数据

    <ListViewandroid:id="@+id/listViewTodayForcast"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintTop_toBottomOf="@id/textViewWeather"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"/>

8.最后的结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/16948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8s安全配置:CIS基准与kube-bench工具

01、概述 K8s集群往往会因为配置不当导致存在入侵风险&#xff0c;如K8S组件的未授权访问、容器逃逸和横向攻击等。为了保护K8s集群的安全&#xff0c;我们必须仔细检查安全配置。 CIS Kubernetes基准提供了集群安全配置的最佳实践&#xff0c;主要聚焦在两个方面&#xff1a;主…

C语言指针进阶-2

本篇文章带 1. 数组传参和指针传参 2. 函数指针 3. 函数指针数组 的相关知识详细讲解&#xff01; 如果您觉得文章不错&#xff0c;期待你的一键三连哦&#xff0c;你的鼓励是我创作动力的源泉&#xff0c;让我们一起加油&#xff0c;一起奔跑&#xff0c;让我们顶峰相见&…

(文章复现)梯级水光互补系统最大化可消纳电量期望短期优化调度模型matlab代码

参考文献&#xff1a; [1]罗彬,陈永灿,刘昭伟等.梯级水光互补系统最大化可消纳电量期望短期优化调度模型[J].电力系统自动化,2023,47(10):66-75. 1.基本原理 1.1 目标函数 考虑光伏出力的不确定性&#xff0c;以梯级水光互补系统的可消纳电量期望最大为目标&#xff0c;函数…

kernel32.dll如何修复,快速解决kernel32.dll缺失的方法

Kernel32.dll是Windows操作系统中一个重要的系统文件&#xff0c;对于系统的正常运行至关重要。然而&#xff0c;由于各种原因&#xff0c;用户可能会遇到kernel32.dll文件的缺失问题。今天小编就来给大家详细的介绍一下kernel32.dll这个文件&#xff0c;并且详细的介绍一下ker…

Iptables

常用名词 容器&#xff1a;存放东西 表(table)&#xff1a;存放链的容器&#xff0c;防火墙的最大概念 链(chain)&#xff1a;存放规则的容器 规则(policy)&#xff1a;准许或拒绝规则 Iptables处理流程 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上…

小程序通过ip+port+路径获取服务器中的图片

配置IIS 首先需要配置IIS。 打开控制面板&#xff0c;接下来的流程按下图所示。 安装好后&#xff0c;按“win”键&#xff0c;搜索IIS 选择一个ip地址&#xff0c;或手动填写&#xff0c;端口号按需更改 填写别名和物理路径&#xff0c;别名就是后续通过url访问物理…

html5播放器视频切换和连续播放的实例

当前播放器实例可以使用changeVid接口切换正在播放的视频。当有多个视频&#xff0c;在上一个视频播放完毕时&#xff0c;自动播放下一个视频时也可采用该处理方式。 const option {vid: 88083abbf5bcf1356e05d39666be527a_8,//autoplay: true,//playsafe: , //PC端播放加密视…

牛客网Verilog刷题——VL41

牛客网Verilog刷题——VL41 题目答案 题目 请设计一个可以实现任意小数分频的时钟分频器&#xff0c;比如说8.7分频的时钟信号&#xff0c;注意rst为低电平复位。提示&#xff1a;其实本质上是一个简单的数学问题&#xff0c;即如何使用最小公倍数得到时钟周期的分别频比。设小…

数据中台系列2:rabbitMQ 安装使用之 window 篇

RabbitMQ 是一个开源的消息队列系统&#xff0c;是高级消息队列协议&#xff08;AMQP&#xff09;的标准实现&#xff0c;用 erlang 语言开发。 因此安装 RabbitMQ 之前要先安装好 erlang。 1、安装 erlang 到 这里 下载本机能运行的最新版 erlang 安装包。如果本机没有装过 …

Mac/win开发快捷键、vs插件、库源码、开发中的专业名词

目录 触控板手势&#xff08;2/3指&#xff09; 鼠标右键 快捷键 鼠标选择后shift⬅️→改变选择 mac command⬅️&#xff1a;删除←边的全部内容 commadtab显示下栏 commandshiftz向后撤回 commandc/v复制粘贴 command ⬅️→回到行首/末 commandshift3/4截图 飞…

PHP使用PhpSpreadsheet实现导出Excel时带下拉框列表 (可支持三级联动)

因项目需要导出Excel表 需要支持下拉 且 还需要支持三级联动功能 目前应为PHPExcel 不在维护&#xff0c;固采用 PhpSpreadsheet 效果如图&#xff1a; 第一步&#xff1a;首先 使用composer 获取PhpSpreadsheet 我这里PHP 版本 7.4 命令如下&#xff1a; composer r…

富士通“Actlyzer”提供基于AI的基于视频的行为分析

想象一下这样的场景&#xff1a;一个男人走近一个家的前门&#xff0c;蹲下并检查钥匙孔。这是丢失房屋钥匙的居民还是客人&#xff1f;还是寻找入口点的窃贼&#xff1f;“Actlyzer”是一种新的人工智能安全系统&#xff0c;旨在区分这种情况。富士通实验室和研发中心的行为分…

k8s安装Jenkins

目录 ​编辑 一、环境准备 1.1 环境说明 二、安装nfs 2.1 安装NFS 2.2 创建NFS共享文件夹 2.3 配置共享文件夹 2.4 使配置生效 2.5 查看所有共享目录 2.6 启动nfs 2.7 其他节点安装nfs-utils 三、创建PVC卷 3.1 创建namespace 3.2 创建nfs 客户端sa授权 3.3 创建…

XtraBackup 8.0.33-28 prepare 速度提升 20 倍!

在这篇博文中&#xff0c;我们将描述 Percona XtraBackup 8.0.33-28 的改进&#xff0c;这显著减少了备份准备所需的时间&#xff0c;以便进行恢复操作。 Percona XtraBackup 中的这一改进显着缩短了新节点加入 Percona XtraDB 集群&#xff08;PXC&#xff09; 所需的时间。 …

Python - OpenCV识别条形码、二维码(已封装,拿来即用)

此代码可识别条形码和二维码&#xff0c;已封装好&#xff0c;拿来即用&#xff1a; import cv2 import pyzbar.pyzbar as pyzbar import numpy from PIL import Image, ImageDraw, ImageFontclass CodeScan():def __init__(self):super(CodeScan, self).__init__()def decode…

阿丹千问vue页面升级-使用Markdown形式展示回答--markdown-it库

阿丹&#xff1a; 在之前开发的阿丹千问 发现回复的文章格式使用 Markdown的格式。所以想使用Markdown的方式来给页面来个升级。 下面就是升级以及开发的过程。 升级思路 使用vue中的markdown-it库 在Vue页面中使用Markdown文档 安装markdown-it&#xff1a; 在Vue项目中…

【活动总结】0730-COC深圳社区AI●CMeetup第4期——畅谈AI+智能制造与机器人的现状与未来

【活动总结】0730-COC深圳社区AI●CMeetup第4期——畅谈AI智能制造与机器人的现状与未来 在过去的半年里&#xff0c;AI 相关技术取得了革命性突破&#xff0c;CSDN CMeet策划推出系列研讨会&#xff0c;深度探讨技术更新后的开发实践。然而&#xff0c;更重要的是如何对 AI 实…

设计模式:生成器模式

这个模式书上讲的比较简单&#xff0c;但是感觉精华应该是讲到了。 引用下其它博客的总结&#xff1a;生成器模式的核心在于分离构建算法和具体的构造实现&#xff0c;从而使得构建算法可以重用。 【设计模式】建造者模式_鼠晓的博客-CSDN博客

fiddler过滤器

1、fiddler Fiddler是一个免费、强大、跨平台的HTTP抓包工具。下载地址 2、为什么适用过滤器 不适用过滤器时&#xff0c;所有的报文都会被抓包。 我们在开发或测试时&#xff0c;只需要抓包某个域名下的报文 &#xff0c;以“www.baidu.com”为例&#xff0c;不设置过滤器&…

iOS开发-实现3DTouch按压App快捷选项shortcutItems及跳转功能

iOS开发-实现3DTouch按压App快捷选项shortcutItems及跳转功能 App的应用图标通过3D Touch按压App图标&#xff0c;会显示快捷选项&#xff0c;点击选项可快速进入到App的特定页面。 这里用到了UIApplicationShortcutItem与UIMutableApplicationShortcutItem 一、效果图 这里…