kotlin 编写一个简单的天气预报app(二)

增加界面显示openweathermap返回的信息。

在activity_main.xml里增加输入框来输入城市,在输入款旁边增加搜索按钮来进行查询。
然后原来显示helloworld的TextView用来显示结果。

1. 增加输入城市名字的EditText

    <EditText
        android:id="@+id/editTextCity"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:hint="@string/editTextCityHint"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/buttonSearch"/>
  1. 增加搜索按钮
    <Button
        android:id="@+id/buttonSearch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="@+id/editTextCity"
        app:layout_constraintBottom_toBottomOf="@+id/editTextCity"
        app:layout_constraintStart_toEndOf="@+id/editTextCity"
        app:layout_constraintEnd_toEndOf="parent"
        android:text="@string/buttonSearchText" />

3. 增加显示的TextView

    <TextView
        android:id="@+id/weatherResult"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

使用broadcast的方式把收到的天气信息发送到界面显示。
Android的广播机制是一种用于在应用程序内和应用程序之间传递消息和事件的方式。通过广播,一个应用程序可以发送消息(被称为广播),而其他应用程序可以接收并处理这些广播。

  • 广播发送者(Broadcast Sender):应用程序或者系统组件(如系统服务)可以通过发送广播来通知其他应用程序或组件事件的发生。广播发送者并不需要知道接收者是谁,只需要发送广播即可。
  • 广播接收者(Broadcast Receiver):应用程序或者组件可以通过注册广播接收器来接收特定类型的广播。广播接收者可以在AndroidManifest.xml文件中声明静态接收器,也可以在代码中动态注册接收器。
  • 广播的类型:Android广播可以分为普通广播和有序广播两种类型。
  • 普通广播(Normal Broadcast):普通广播是一种异步的广播发送方式,广播发送者不需要等待接收者处理广播。这使得广播发送者能够快速地发送广播,而不会受到接收者处理时间的影响。
  • 有序广播(Ordered Broadcast):有序广播是一种同步的广播发送方式,广播发送者会按照优先级的顺序发送广播,接收者依次处理广播。每个接收者处理完广播后可以选择终止广播或者将广播传递给下一个接收者。
  • 广播过滤器(Broadcast Filter):广播过滤器允许应用程序指定它们所感兴趣的广播类型。广播接收者可以根据广播过滤器过滤来自特定来源或具有特定操作的广播。这样可以减少不必要的广播传递,提高性能。
  • 系统广播(System Broadcast):Android系统内置了一些广播用于通知应用程序和组件系统事件的发生,例如设备启动、网络连接状态变化、电池低电量等。应用程序可以注册对这些系统广播感兴趣的接收者,以执行相应的操作。
    通过广播机制,应用程序可以实现一种松耦合的通信方式,让不同的组件之间进行信息传递和事件触发。这种机制使得应用程序能够更好地响应系统事件、应用程序状态的变化,并且可以与其他应用程序之间进行交互。

4.注册一个自定义的广播:

将广播接收器的类名替换为您自己的接收器类名,并使用 intent-filter 添加您自定义的广播 action。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <uses-permission android:name="android.permission.INTERNET" />
    <application
<!--   			... -->
        <activity
<!--   			... -->
        </activity>
        <receiver
            android:name=".WeatherResponseReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.example.MyWeather.ACTION_WEATHER_DATA"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

5.在RetrofitClient类中发送广播

在发送自定义广播时,您需要使用 sendBroadcast() 方法,并指定广播的 action。

    private fun handleWeatherData(context: Context, weatherData: WeatherResponse?) {
        if (weatherData != null) {
            val intent = Intent("com.example.MyWeather.ACTION_WEATHER_DATA")
            intent.putExtra("cityName", weatherData.name)
            intent.putExtra("temperature", weatherData.main?.temp)
            intent.putExtra("maxTemperature", weatherData.main?.temp_max)
            intent.putExtra("minTemperature", weatherData.main?.temp_min)
            val weatherStringArray = arrayListOf<String>()
            for(weather in weatherData.weather) {
                weatherStringArray += "main:${weather.main},description:${weather.description}"
            }
            intent.putStringArrayListExtra("weather", weatherStringArray)
            context.sendBroadcast(intent)

            printWeatherData(weatherData)
        }
    }

6.创建一个用来接受广播的类,并重写onReceive函数。

class WeatherResponseReceiver : BroadcastReceiver() {
    private var textView: TextView? = null

    fun setTextView(textView: TextView) {
        this.textView = textView
    }


    override fun onReceive(context: Context?, intent: Intent?) {
        if(intent?.action == "com.example.MyWeather.ACTION_WEATHER_DATA") {
            val kelvins = 273.15
            val cityName = intent.getStringExtra("cityName")
            val temperature = intent.getFloatExtra("temperature", 0.0F) - kelvins
            val maxTemperature = intent.getFloatExtra("maxTemperature", 0.0F) - kelvins
            val minTemperature = intent.getFloatExtra("minTemperature", 0.0F) - kelvins
            val weather = intent.getStringArrayListExtra("weather")
            val decimalFormat = DecimalFormat("#.#")

            @SuppressLint("SetTextI18n")
            textView?.text = "$cityName\n${decimalFormat.format(temperature)}\n${decimalFormat.format(maxTemperature)}\n${decimalFormat.format(minTemperature)}\n$weather"
        }
    }
}

为了能让收到的广播消息能够显示在TextView中,我把TextView的指针传递给了接收广播的类。

class MainActivity : AppCompatActivity() {
    private lateinit var weatherResponseReceiver: WeatherResponseReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        weatherResponseReceiver = WeatherResponseReceiver()
        weatherResponseReceiver.setTextView(findViewById<TextView>(R.id.weatherResult))
        val intentFilter = IntentFilter("com.example.MyWeather.ACTION_WEATHER_DATA")
        registerReceiver(weatherResponseReceiver, intentFilter)

        findViewById<Button>(R.id.buttonSearch).setOnClickListener { searchCityNameWeather(it) }
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(weatherResponseReceiver)
    }

    private fun searchCityNameWeather(view: View) {
        val cityName = findViewById<EditText>(R.id.editTextCity).text.toString().trim()
        RetrofitClient.getWeatherByCityName(view.context, cityName)
    }
}

7.最后的测试结果:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于机器学习的供水管网水力模型

大数据、人工智能、物联网等前沿技术正推动人类社会发展发生深刻变革。2021年12月12日&#xff0c;国务院印发了《“十四五”数字经济发展规划》&#xff0c;进一步指明了各行业数字化转型发展的方向。作为传统的民生保障行业&#xff0c;供水行业也面临着向数字化智慧化转型的…

MySQL5.7 与 MariaDB10.1 审计插件兼容性验证

这是一篇关于发现 MariaDB 审计插件导致 MySQL 发生 crash 后&#xff0c;展开适配验证并进行故障处理的文章。 作者&#xff1a;官永强 爱可生DBA 团队成员&#xff0c;擅长 MySQL 运维方面的技能。热爱学习新知识&#xff0c;亦是个爱打游戏的宅男。 本文来源&#xff1a;原创…

利用mysqldump实现分库分表备份的shell脚本

一、信息摘要 linux版本&#xff1a;CentOS 7.9 mysql版本&#xff1a;MySQL 5.7.36 脚本实现功能&#xff1a;利用mysqldump工具实现对mysql中的数据库分库备份&#xff0c;和对所备份数据库中的表分表备份 二、shell脚本 #!/bin/bash ######################### #File n…

【雕爷学编程】MicroPython动手做(09)——零基础学MaixPy之人脸识别2

自己打包kfpkg&#xff0c;试着整了好几次&#xff0c;都是无法烧录&#xff0c;只好不做第七步了&#xff0c;直接把前面获得的人脸识别模型烧录了 烧录完成后&#xff0c;打开IDE串口&#xff0c;确认开发板Maixpy固件的版本&#xff0c;好像是前期的稳定版本V0.4.0 第九步&a…

LaTeX Error: File `tabu.sty‘ not found.

虽然Miktex可以自动下载和安装没有的库&#xff0c;但有些时候也有可能会直接报错&#xff1a; LaTeX Error: File tabu.sty not found. 解决方法就是打开控制台。然后手动下载&#xff1a;

WPF快速开发(2):图标库知识点

文章目录 前言知识点windows资源Style:样式Setter:属性继承关系 Trigger:触发器 WPF层级划分数据绑定声明数据上下文绑定数据模板 前言 图标资源下载 iconfont 知识点 windows资源 Window.Resources&#xff1a;资源位置声明X:Key&#xff1a;资源Id&#xff0c;用于前端的…

【C++】 函数模板和类模板

文章目录 一、模板1.1 函数模板和类模板1.2 函数模板1.2.1 普通函数和函数模板区别1.2.2 普通函数和函数模板调用规则1.2.3 模板局限性 1.3 类模板1.3.1 类模板对象做函数参数1.3.2 类模板的继承1.3.3 类模板成员函数的类外实现1.3.4 类模板分文件编写1.3.5 类模板全局函数类内…

Cookie 和 Session 区别——2023最新面试精简版本

Cookie 和 Session 的区别 原理&#xff1a;从”登录“过程看Jwt和Token&#xff0c;以及区分Cookie和Session概念 面试&#xff1a; 好的&#xff0c;面试官。 我先解释一下 Cookie&#xff0c;它是客户端浏览器用来保存服务端数据的一种机制。 当通过浏览器进行网页访问的时…

echarts坐标轴名称换行

一、期望效果&#xff1a; 期望超过6个字换行&#xff0c;最多可显示十个字 如图&#xff1a; 二、踩坑&#xff1a; echarts的width和overflow设置后换行无效。&#xff08;如果其他人有设置有效的 还请说明下&#xff09; 三、解决方案&#xff1a; 用\n换行&#xf…

CSS :nth-child

CSS :nth-child :nth-child 伪类根据元素在同级元素中的位置来匹配元素. CSS :nth-child 语法 值是关键词 odd/evenAnB最新的 [of S] 语法权重 浏览器兼容性 很简单的例子, 来直觉上理解这个伪类的意思 <ul><li class"me">Apple</li><li>B…

14.Netty源码之模拟简单的HTTP服务器

highlight: arduino-light 简单的 HTTP 服务器 HTTP 服务器是我们平时最常用的工具之一。同传统 Web 容器 Tomcat、Jetty 一样&#xff0c;Netty 也可以方便地开发一个 HTTP 服务器。我从一个简单的 HTTP 服务器开始&#xff0c;通过程序示例为你展现 Netty 程序如何配置启动&a…

智能视频监控平台EasyCVR电子地图视频播放全屏情况下的异常排查与解决

安防视频监控平台TSINGSEE青犀视频EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 在视频监控管理平台TSINGSEE青…

Vue项目中强制刷新页面的方法

我们在动态切换组件的过程中&#xff0c;导航栏和底栏不动&#xff0c;动态切换中间区域的情况&#xff0c;在首页可以进行跳转任意组件&#xff0c;在组件与组件之间不能相互跳转&#xff0c;路由发生了变化&#xff0c;但是页面未改变&#xff0c;这时我们就需要强制刷新页面…

Individual household electric power consumption个人家庭用电量数据挖掘与时序预测建模

今天接到一个任务就是需要基于给定的数据集来进行数据挖掘分析相关的计算&#xff0c;并完成对未来时段内数据的预测建模&#xff0c;话不多少直接看内容。 官方数据详情介绍在这里&#xff0c;如下所示&#xff1a; 数据集中一共包含9个不同的字段&#xff0c;详情如下&#…

AP5216 DC-DC降恒流驱动IC LED电动摩托汽车 转向灯刹车灯雾灯驱动

产品描述 AP5216 是一款 PWM工作模式, 高效率、外围简单、内置功率管&#xff0c;适用于5V&#xff5e;100V输入的高精度降压 LED 恒流驱动芯片。输出最大功率可达9W&#xff0c;最大电流 1.0A。AP5216 可实现全亮/半亮功能切换&#xff0c;通过MODE 切换&#xff1a;全亮/半亮…

序列化模块pickle和json有什么区别

目录 什么是序列化模块pickle 什么是序列化模块json pickle和json有什么区别 总结 什么是序列化模块pickle pickle是Python中的内置模块&#xff0c;用于将Python对象序列化和反序列化为字节流。它提供了一种将复杂的数据结构&#xff08;如列表、字典、类实例等&#xff0…

字典树Trie

Trie树又称字典树&#xff0c;前缀树。是一种可以高效查询前缀字符串的树&#xff0c;典型应用是用于统计&#xff0c;排序和保存大量的字符串&#xff08;但不仅限于字符串&#xff09;&#xff0c;所以经常被搜索引擎系统用于文本词频统计。 它的优点是&#xff1a;利用字符串…

【图像处理】使用 OpenCV 将您的照片变成卡通

图像到卡通 一、说明 在当今世界&#xff0c;我们被图像和视频所包围。从社交媒体到广告&#xff0c;图像已成为一种强大的交流媒介。但是你有没有想过&#xff0c;如果你能把你的照片变成卡通会发生什么&#xff1f;想象一下&#xff0c;为您最喜欢的照片创建动画版本&#xf…

CSP 2021入门级 第一轮 题目讲解

A: a进栈&#xff0c;直接出栈&#xff1b;b进栈&#xff0c;直接出栈&#xff1b;c进栈&#xff0c;直接出栈&#xff1b;d进栈&#xff0c;直接出栈&#xff1b;e进栈&#xff0c;直接出栈。 B&#xff1a;全进栈后全出栈。 C&#xff1a;a和b先进栈&#xff0c;然后直接出…

网络安全(黑客)自学建议笔记

前言 网络安全&#xff0c;顾名思义&#xff0c;无安全&#xff0c;不网络。现如今&#xff0c;安全行业飞速发展&#xff0c;我们呼吁专业化的 就职人员与大学生 &#xff0c;而你&#xff0c;认为自己有资格当黑客吗&#xff1f; 本文面向所有信息安全领域的初学者和从业人员…