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.最后的结果:
相关文章:

kotlin 编写一个简单的天气预报app(五)增加forcast接口并显示
参考资料 OpenWeatherMap提供了一个/forecast接口,用于获取未来几天的天气预报。你可以使用HTTP GET请求访问该接口,并根据你所在的城市或地理坐标获取相应的天气数据。 以下是一个示例请求的URL和一些常用的参数: URL: http://api.openwe…...

vs调试引发了异常:读取访问权限冲突,argv是0x7
vs2019写了几句小代码,结果报错: 引发了异常:读取访问权限冲突,argv是0x7 查了一堆是什么数组越界了,空指针异常了啥的。 只好都注释掉只留下主函数,结果还是报错,定睛一看才发现原因:main函数忘写第一…...

【电影推荐系统】实时推荐
概览 技术方案: 日志采集服务:通过利用Flume-ng对业务平台中用户对于电影的一次评分行为进行采集,实时发送到Kafka集群。消息缓冲服务:项目采用Kafka作为流式数据的缓存组件,接受来自Flume的数据采集请求。并将数据推…...

Delphi 开发不一样的窗体标题栏:TTitleBarPanel
目录 TTitleBarPanel 的使用 TTitleBarPanel 的使用进阶 一、设置标题栏高度、颜色 二、个性化标题栏的关闭等按键 我们在用Delphi开发程序的时候,窗体的标题栏一般都是标准的windows标题栏,上面包括:程序图标、标题、最小化、最大化、关闭…...

Quartz中禁止并发机制源码级解析
文章目录 Quartz进行任务调度时通常会要求一个任务禁止并发执行,此时只需要在Job类上面添加一个注解DisallowConcurrentExecution即可。在保存到数据库里面时,对应QRTZ_JOB_DETAILS表中的IS_NONCONCURRENT字段的值为1(true)。那么…...

为什么从公有云迁移到私有云的越来越多?
随着云计算的快速发展,越来越多的组织开始考虑将其IT基础设施从公有云迁移到私有云。这种转变背后存在着一系列的原因和动机,下面我们将探讨一些常见的迁移原因。 首先,数据安全和隐私是许多组织选择私有云的主要原因之一。在公有云中&#…...

用shell实现MySQL分库分表操作
#!/bin/bash mysql_cmd-uroot -p123 #定义变量保存密码 exclude_dbinformation_schema|performance_schema|sys #数据库 bak_path/backup/db #备份路径 mysql ${mysql_cmd} -e show databases -N | egrep -v "${exclude_db}" > dbname while read line do …...

php 适配器模式
一,适配器模式,属于结构设计模式的一种,用于将一个类的接口转换成客户期望的接口。 1,目标接口(Target Interface):是客户期望的接口,定义了客户要调用的方法。 2,适配器…...

Scratch Blocks自定义组件之「下拉图标」
一、背景 由于自带的下拉图标是给水平布局的block使用,放在垂直布局下显得别扭,而且下拉选择后回修改image字段的图片,这让我很不爽,所以在原来的基础上稍作修改,效果如下: 二、使用说明 (1&am…...

Robot Framweork之UI自动化测试---分层设计
Robot Framework 的分层思想是一种测试设计和代码组织的模式,它将测试用例的实现和测试执行逻辑分离,以提高测试的可维护性、可读性和可扩展性。 一、分层思想 在实际项目中,一般分为三层:元素层,流程层,用…...

MySQL8.0/8.x更新用户密码命令
authentication_string 这是Mysql8.0新做出的修改,在旧版本中使用的是password()函数。 2,在网上找到的mysql忘记密码的解决方案中,大多会使用 UPDATE user SET authentication_string12345 WHERE userroot; 来直接将密码改成12345࿰…...

【MySQL】下载安装以及SQL介绍
1,数据库相关概念 以前我们做系统,数据持久化的存储采用的是文件存储。存储到文件中可以达到系统关闭数据不会丢失的效果,当然文件存储也有它的弊端。 假设在文件中存储以下的数据: 姓名 年龄 性别 住址 张三 23 男 北京…...

算法题--二叉树(二叉树的最近公共祖先、重建二叉树、二叉搜索树的后序遍历序列)
目录 二叉树 题目 二叉树的最近公共祖先 原题链接 解析 二叉搜索树的最近公共节点 核心思想 答案 重建二叉树 题目链接 解析 核心思想 答案 二叉搜索树的后序遍历序列 原题链接 解析 核心思想 答案 二叉树 该类题目的解决一般是通过节点的遍历去实现&#x…...

mysql的基础面经-索引、事务
1 聚簇索引 1 和主键索引的关系 2 和非聚簇索引的关系,其叶子节点存储的是聚簇索引中的主键 3 索引覆盖机制使得非聚簇索引不用回表二次查询 2 举一个使用索引覆盖的例子 我的项目中没有使用到覆盖索引,但是可以举一个例子,比如我直接为年…...

Windows下双网卡配置静态路由,实现内外网同时使用
怎么样设置双网卡?内网外网两个网络这么同时连接? 接下来听好了,赶紧动手 情况描述: 我使用的Windows10电脑,支持双网卡工作 目前我工作需要使用的使用内网,但是又需要使用外网,需要同时使用&a…...

Spring整合Mybatis、Spring整合JUnit
🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaweb 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 Spring整合 一、Spring整合Mybatis1.1 整合Mybatis&#x…...

Devops系统中jira平台迁移
需求:把aws中的devops系统迁移到华为云中,其中主要是jira系统中的数据迁移,主要方法为在华为云中建立一套 与aws相同的devops平台,再把数据库和文件系统中的数据迁移,最后进行测试。 主要涉及到的服务集群CCE、数据库mysql、弹性文件服务SFS、数据复制DRS、弹性负载均衡ELB。 迁…...

【雕爷学编程】MicroPython动手做(29)——物联网之SIoT
知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...

LAXCUS分布式操作系统引领科技潮流,进入百度首页
信息源自某家网络平台,以下原样摘抄贴出。 随着科技的飞速发展,分布式操作系统做为通用基础平台,为大数据、高性能计算、人工智能提供了强大的数据和算力支持,已经成为了当今计算机领域的研究热点。近日,一款名为LAXCU…...

Linux--按行读取数据:fgets
函数定义: char *fgets(char *s,int size,FILE *stream); S是指接受数据缓冲区,用于存放stream里读取的数据 size是指缓冲区的大小 返回值为NULL表明读取失败,反之读取成功...

express学习笔记5 - 自定义路由异常处理中间件
修改router/index.js,添加异常处理中间件 *** 自定义路由异常处理中间件* 注意两点:* 第一,方法的参数不能减少* 第二,方法的必须放在路由最后*/ router.use((err, req, res, next) > {console.log(err);const msg (err &…...

filebeat介绍
1、filebeat概述 Filebeat是用于转发和集中日志数据的轻量级传送工具。Filebeat监视您指定的日志文件或位置,收集日志事件,并将它们转发到Elasticsearch或 Logstash或kafka进行索引 1.1 Filebeat两个主要组件 prospector 和 harvester。 prospector&a…...

使用SSM框架实现个人博客管理平台以及实现Web自动化测试
文章目录 前言1. 项目概述2. 项目需求2.1功能需求2.2 其他需求2.3 系统功能模块图 3. 开发环境4. 项目结构5. 部分功能介绍5.1 数据库密码密文存储5.2 统一数据格式返回5.3 登录拦截器 6. 项目展示7. 项目测试7.1 测试用例7.2 执行部分自动化测试用例 前言 在几个月前实现了一…...

【深度学习】MAT: Mask-Aware Transformer for Large Hole Image Inpainting
论文:https://arxiv.org/abs/2203.15270 代码:https://github.com/fenglinglwb/MAT 文章目录 AbstractIntroductionRelated WorkMethod总体架构卷积头Transformer主体Adjusted Transformer Block Multi-Head Contextual Attention Style Manipulation Mo…...

PyTorch BatchNorm2d详解
通常和卷积层,激活函数一起使用...

慕课网Go-4.package、单元测试、并发编程
package 1_1_User.go package usertype User struct {Name string }1_1_UserGet.go package userfunc GetCourse(c User) string {return c.Name }1_1_UserMain.go package mainimport ("fmt"Userch03 "goproj/IMOOC/ch03/user"//别名,防止同名…...

[JavaWeb]SQL介绍-DDL-DML
SQL介绍-DDL-DML 一.SQL简介1.简介2.SQL通用语法3.SQL语言的分类 二.DDL-操作数据库与表1.DDL操作数据库2.DDL操作表①.查询表(Retrieve)②.创建表(Create)③.修改表(Update)④.删除表(Delete) 三.Navicat的安装与使用四.DML-操作表数据1.添加(Insert)2.修改(Update)3.删除(Del…...

git源码安装(无sudo权限)
git源码安装(无sudo权限) 下载源码解压安装添加到环境变量 下载源码 去https://mirrors.edge.kernel.org/pub/software/scm/git/下载需要的版本。我下载的是2.41.0版本 wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.41.0.tar.gz解…...

Web3 叙述交易所授权置换概念 编写transferFrom与approve函数
前文 Web3带着大家根据ERC-20文档编写自己的第一个代币solidity智能合约 中 我们通过ERC-20一种开发者设计的不成文规定 也将我们的代币开发的很像个样子了 我们打开 ERC-20文档 我们transfer后面的函数就是transferFrom 这个也是 一个账号 from 发送给另一个账号 to 数量 val…...

Redis系列二:Clion+MAC+Redis环境搭建
1. ClionMACRedis-3.0-annotated环境搭建 参考: https://github.com/huangz1990/redis-3.0-annotated https://gitee.com/dumpcao/redis-3.0-annotated-cmake-in-clion https://tool.4xseo.com/a/12910.html 1.1 下载并导入Clion git clone https://gitee.com/dum…...