当前位置: 首页 > news >正文

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接口&#xff0c;用于获取未来几天的天气预报。你可以使用HTTP GET请求访问该接口&#xff0c;并根据你所在的城市或地理坐标获取相应的天气数据。 以下是一个示例请求的URL和一些常用的参数&#xff1a; URL: http://api.openwe…...

vs调试引发了异常:读取访问权限冲突,argv是0x7

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

【电影推荐系统】实时推荐

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

Delphi 开发不一样的窗体标题栏:TTitleBarPanel

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

Quartz中禁止并发机制源码级解析

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

为什么从公有云迁移到私有云的越来越多?

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

用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 适配器模式

一&#xff0c;适配器模式&#xff0c;属于结构设计模式的一种&#xff0c;用于将一个类的接口转换成客户期望的接口。 1&#xff0c;目标接口&#xff08;Target Interface&#xff09;&#xff1a;是客户期望的接口&#xff0c;定义了客户要调用的方法。 2&#xff0c;适配器…...

Scratch Blocks自定义组件之「下拉图标」

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

Robot Framweork之UI自动化测试---分层设计

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

MySQL8.0/8.x更新用户密码命令

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

【MySQL】下载安装以及SQL介绍

1&#xff0c;数据库相关概念 以前我们做系统&#xff0c;数据持久化的存储采用的是文件存储。存储到文件中可以达到系统关闭数据不会丢失的效果&#xff0c;当然文件存储也有它的弊端。 假设在文件中存储以下的数据&#xff1a; 姓名 年龄 性别 住址 张三 23 男 北京…...

算法题--二叉树(二叉树的最近公共祖先、重建二叉树、二叉搜索树的后序遍历序列)

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

mysql的基础面经-索引、事务

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

Windows下双网卡配置静态路由,实现内外网同时使用

怎么样设置双网卡&#xff1f;内网外网两个网络这么同时连接&#xff1f; 接下来听好了&#xff0c;赶紧动手 情况描述&#xff1a; 我使用的Windows10电脑&#xff0c;支持双网卡工作 目前我工作需要使用的使用内网&#xff0c;但是又需要使用外网&#xff0c;需要同时使用&a…...

Spring整合Mybatis、Spring整合JUnit

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

Devops系统中jira平台迁移

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

【雕爷学编程】MicroPython动手做(29)——物联网之SIoT

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…...

LAXCUS分布式操作系统引领科技潮流,进入百度首页

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

Linux--按行读取数据:fgets

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

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...