基于Android平台开发,天气预报APP

1.项目功能思维导图

在这里插入图片描述

2. 项目涉及到的技术点

  1. 数据来源:和风天气API
  2. 使用okhttp网络请求框架获取api数据
  3. 使用gson库解析json数据
  4. 使用RecyclerView+adapter实现未来7天列表展示和天气指数
  5. 使用PopupMenu 实现弹出选项框
  6. 使用动画+定时器实现欢迎页倒计时和logo动画
  7. 使用TextToSpeech 实现语音播报

3.项目截图

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

4.部分代码功能实现

  1. 欢迎页实现
public class WelcomeActivity extends AppCompatActivity {private TextView tvCountdown;private CardView card_logo;private CountDownTimer countDownTimer;private long timeLeftInMillis = 1000; // 设置倒计时时长,单位为毫秒@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_welcome);//初始化控件tvCountdown = findViewById(R.id.tv_countdown);card_logo = findViewById(R.id.card_logo);// 启动倒计时startCountdown();//实现logo缩放动画startAnim();}private void startAnim() {ViewCompat.animate(card_logo).scaleX(1.0f).scaleY(1.0f).setDuration(1000).setListener(new ViewPropertyAnimatorListener() {@Overridepublic void onAnimationStart(View view) {}@Overridepublic void onAnimationEnd(View view) {}@Overridepublic void onAnimationCancel(View view) {}}).start();}private void startCountdown() {countDownTimer = new CountDownTimer(timeLeftInMillis, 1000) {@Overridepublic void onTick(long millisUntilFinished) {timeLeftInMillis = millisUntilFinished;int secondsRemaining = (int) (millisUntilFinished / 1000);tvCountdown.setText(secondsRemaining + "s | 跳转");}@Overridepublic void onFinish() {//跳转到登录页面(看自己逻辑想跳转哪个页面)startActivity(new Intent(WelcomeActivity.this, MainActivity.class));// 倒计时结束后的操作,例如跳转到主页面finish();}}.start();}@Overrideprotected void onDestroy() {super.onDestroy();if (countDownTimer != null) {countDownTimer.cancel();}}
}
  1. 天气指数
public class IndicesActivity extends AppCompatActivity {private String city_id;private RecyclerView recyclerView;private IndicesListAdapter mIndicesListAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_indices);//获取跳转传值city_id = getIntent().getStringExtra("city_id");//获取生活指数getWeatherIndices(city_id);//初始化控件initViews();//初始化适配器mIndicesListAdapter = new IndicesListAdapter();//设置适配器recyclerView.setAdapter(mIndicesListAdapter);//设置监听器setListener();}/*** 初始化控件*/private void initViews() {recyclerView = findViewById(R.id.recyclerView);}/*** 设置监听器*/private void setListener() {findViewById(R.id.toolbar).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {finish();}});}/*** 获取生活指数*/private void getWeatherIndices(String city_id) {OkGo.<String>get("https://devapi.qweather.com/v7/indices/1d").params("location", city_id).params("key", ApiConstants.APP_KEY).params("type", "0").execute(new StringCallback() {@Overridepublic void onStart(Request<String, ? extends Request> request) {super.onStart(request);ProgressDialogUtils.showProgressDialog(IndicesActivity.this);}@Overridepublic void onSuccess(Response<String> response) {IndicesInfo indicesInfo = new Gson().fromJson(response.body(), IndicesInfo.class);if (null != indicesInfo && indicesInfo.getCode().equals("200")) {mIndicesListAdapter.setIndicesInfoList(indicesInfo.getDaily());}}@Overridepublic void onFinish() {super.onFinish();ProgressDialogUtils.hideProgressDialog();}});}
}
  1. 城市搜索
public class SearchActivity extends AppCompatActivity {private EditText et_search_city;private RecyclerView recyclerView;private LinearLayoutCompat ll_empty;private SearchListAdapter mSearchListAdapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_search);// 1. 初始化控件initViews();//创建适配器mSearchListAdapter = new SearchListAdapter();//设置适配器recyclerView.setAdapter(mSearchListAdapter);// 2. 点击事件setListener();}/*** 初始化控件*/private void initViews() {et_search_city = findViewById(R.id.et_search_city);recyclerView = findViewById(R.id.recyclerView);ll_empty = findViewById(R.id.ll_empty);}/*** 点击事件*/private void setListener() {findViewById(R.id.btn_search).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {// 1. 获取输入框的值String cityName = et_search_city.getText().toString().trim();// 2. 判断是否为空if (cityName.isEmpty()) {// 提示用户Toast.makeText(SearchActivity.this, "城市名不能为空", Toast.LENGTH_SHORT).show();} else {searchCity(cityName);}}});//返回findViewById(R.id.toolbar).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {finish();}});//recyclerView点击事件mSearchListAdapter.setOnItemClickListener(new SearchListAdapter.OnItemClickListener() {@Overridepublic void onItemClick(CityLocationInfo.LocationDTO locationDTO) {// 1. 获取城市名String cityName = locationDTO.getName();Intent intent = new Intent();intent.putExtra("cityName", cityName);intent.putExtra("id", locationDTO.getId());//设置跳转回传的值setResult(1000, intent);// 3. 关闭当前界面finish();}});}/*** 城市搜索*/private void searchCity(String cityName) {OkGo.<String>get("https://geoapi.qweather.com/v2/city/lookup").params("location", cityName).params("key", ApiConstants.APP_KEY).execute(new StringCallback() {@Overridepublic void onStart(Request<String, ? extends Request> request) {super.onStart(request);ProgressDialogUtils.showProgressDialog(SearchActivity.this);}@Overridepublic void onSuccess(Response<String> response) {CityLocationInfo cityLocationInfo = new Gson().fromJson(response.body(), CityLocationInfo.class);if (null != cityLocationInfo && cityLocationInfo.getCode().equals("200")) {if (null != mSearchListAdapter) {mSearchListAdapter.setCityLocationInfoList(cityLocationInfo.getLocation());}//判断是否显示空布局if (mSearchListAdapter.getItemCount() > 0) {ll_empty.setVisibility(View.GONE);} else {ll_empty.setVisibility(View.VISIBLE);}} else {Toast.makeText(SearchActivity.this, "未查询到该城市", Toast.LENGTH_SHORT).show();}}@Overridepublic void onError(Response<String> response) {super.onError(response);}@Overridepublic void onFinish() {super.onFinish();ProgressDialogUtils.hideProgressDialog();}});}
}

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

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

相关文章

解决IDEA每次新建项目都需要重新配置maven的问题

每次打开IDEA都要重新配置maven&#xff0c;这是因为在DEA中分为项目设置和全局设置&#xff0c;这个时候我们就需要去到全局中设置maven了。我用的是IntelliJ IDEA 2023.3.4 (Ultimate Edition)&#xff0c;以此为例。 第一步&#xff1a;打开一个空的IDEA&#xff0c;选择左…

传知代码-多行人姿态检测系统

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 本项目创新在于采用多级网络串联工作来进行目标的行为分析&#xff0c;并使用在视频监控领域&#xff0c;可部署在任何有需要的人员流动密集场所(如医院&#xff0c;机场&#xff0c;养老院等)或者用于空巢…

springboot三层架构详细讲解

目录 springBoot三层架构0.简介1.各层架构1.1 Controller层1.2 Service层1.3 ServiceImpl1.4 Mapper1.5 Entity1.6 Mapper.xml 2.各层之间的联系2.1 Controller 与 Service2.2 Service 与 ServiceImpl2.3 Service 与 Mapper2.4 Mapper 与 Mapper.xml2.5 Service 与 Entity2.6 C…

Java语言程序设计——篇三(1)

选择结构 概述选择单分支if语句例题讲解 双分支if-else语句例题讲解 条件运算符多分支的if-else语句例题讲解 嵌套的if语句例题讲解 switch语句结构例题讲解代码演示运行结果 概述 Java中的控制结构&#xff0c;包括&#xff1a; 1、选择结构( if、if-else、switch ) 2、循环结…

最佳 iPhone 解锁软件工具,可免费下载用于电脑操作的

业内专业人士表示&#xff0c;如果您拥有 iPhone&#xff0c;您一定知道忘记锁屏密码会多么令人沮丧。由于 Apple 的安全功能强大&#xff0c;几乎不可能在没有密码或 Apple ID 的情况下访问锁定的 iPhone。 “当我忘记密码时&#xff0c;如何在没有密码的情况下解锁iPhone&am…

Docker 部署 ShardingSphere-Proxy 数据库中间件

文章目录 Github官网文档ShardingSphere-Proxymysql-connector-java 驱动下载conf 配置global.yamldatabase-sharding.yamldockerdocker-compose.yml Apache ShardingSphere 是一款分布式的数据库生态系统&#xff0c; 可以将任意数据库转换为分布式数据库&#xff0c;并通过数…

Python 轻松生成多种条形码、二维码 (Code 128、EAN-13、QR code等)

条形码和二维码是现代信息交换和数据存储的重要工具&#xff0c;它们将信息以图形的形式编码&#xff0c;便于机器识别和数据处理&#xff0c;被广泛应用于物流、零售、医疗、教育等各领域。 本文将介绍如何使用Python快速生成各种常见的条形码如Code 128、EAN-13&#xff0c;…

20240711 每日AI必读资讯

&#x1f3a8;Runway Gen-3 Alpha 详细使用教程以及提示词指南大全 - 7月9日&#xff0c;著名生成式AI平台Runway在官网公布了&#xff0c;最新发布的文生视频模型Gen-3 Alpha的文本提示教程。 - 从技术层面来说&#xff0c;输入的文本提示会被转换成“向量”&#xff0c;这些…

滑动变阻器在实际应用中需要注意哪些安全事项?

滑动变阻器在实际应用中&#xff0c;为了确保其正常运作及保护电路安全&#xff0c;需要注意以下安全事项&#xff1a; 一、了解并遵守规格参数 最大电阻值和允许通过的最大电流值&#xff1a;使用前&#xff0c;必须清楚滑动变阻器的最大电阻值和允许通过的最大电流值&#x…

基于SAM的零样本相似性评价方法

文章目录 介绍方法SAM编码器相似性指标代码复现介绍 图像转换具有广泛的应用,如风格转换和模态转换,通常是生成具有高度真实和忠实的图像。这些问题仍然很困难,特别是在保存语义结构很重要的时候。传统的图像级相似性度量的用途有限,因为图像的语义是高级的,并且不受对原…

什么样的开放式耳机好用舒服?南卡、倍思、Oladance高人气质量绝佳产品力荐!

​开放式耳机在如今社会中已经迅速成为大家购买耳机的新趋势&#xff0c;深受喜欢听歌和热爱运动的人群欢迎。当大家谈到佩戴的稳固性时&#xff0c;开放式耳机都会收到一致好评。对于热爱运动的人士而言&#xff0c;高品质的开放式耳机无疑是理想之选。特别是在近年来的一些骑…

jitsi 使用JWT验证用户身份

前言 Jitsi Meet是一个很棒的会议系统,但是默认他运行所有人创建会议,这样在某种程度上,我们会觉得他不安全,下面我们就来介绍下使用JWT来验证用户身份 方案 卸载旧的lua依赖性sudo apt-get purge lua5.1 liblua5.1-0 liblua5.1-dev luarocks添加ubuntu的依赖源,有则不需…

内容协商源码解析与自定义 MessageConverter

目录 内容协商 1、引入xml依赖 2、postman分别测试返回json和xml 3、开启浏览器参数方式内容协商功能 4、内容协商原理 5、自定义 MessageConverter 综上 内容协商 根据客户端接收能力不同&#xff0c;返回不同媒体类型的数据。 若客户端无法解析服务端返回的内容&#…

Vatee万腾平台:创新科技,驱动未来

在科技日新月异的今天&#xff0c;每一个创新的火花都可能成为推动社会进步的重要力量。Vatee万腾平台&#xff0c;作为科技创新领域的佼佼者&#xff0c;正以其卓越的技术实力、前瞻性的战略眼光和不懈的探索精神&#xff0c;驱动着未来的车轮滚滚向前。 Vatee万腾平台深知&am…

剖析自闭症孩子玩手的独特之处

自闭症孩子玩手的行为常常具有一些较为独特的特点。 重复性是一个显著的特征。他们可能会以一种几乎相同的方式、节奏和频率反复地摆弄自己的手&#xff0c;例如不停地握拳、张开&#xff0c;或者持续地旋转手腕。 动作的单调性也是常见的。玩手的方式可能较为单一&#xff0c;…

【正点原子i.MX93开发板试用连载体验】简单的音频分类

本文最早发表于电子发烧友论坛&#xff1a; 今天测试的内容是进行简单的音频分类。我们要想进行语音控制&#xff0c;就需要构建和训练一个基本的自动语音识别 (ASR) 模型来识别不同的单词。如果想了解这方面的知识可以参考TensorFlow的官方文档&#xff1a;简单的音频识别&…

矢量绘图设计Sketch中文 Sketch直装安装包

Sketch是一款专为UI设计师和UX专家打造的矢量图形设计软件&#xff0c;以其简洁的界面、强大的功能和高效的协作能力而闻名。Sketch支持快速创建高质量的UI界面、图标、图形和插画&#xff0c;其矢量绘图工具让设计细节更加精准。同时&#xff0c;Sketch内置丰富的插件和组件库…

1-认识网络爬虫

1.什么是网络爬虫 ​ 网络爬虫&#xff08;Web Crawler&#xff09;又称网络蜘蛛、网络机器人&#xff0c;它是一种按照一定规则&#xff0c;自动浏览万维网的程序或脚本。通俗地讲&#xff0c;网络爬虫就是一个模拟真人浏览万维网行为的程序&#xff0c;这个程序可以代替真人…

【xinference】(15):在compshare上,使用docker-compose运行xinference和chatgpt-web项目,配置成功!!!

视频演示 【xinference】&#xff08;15&#xff09;&#xff1a;在compshare上&#xff0c;使用docker-compose运行xinference和chatgpt-web项目&#xff0c;配置成功&#xff01;&#xff01;&#xff01; 1&#xff0c;安装docker方法&#xff1a; #!/bin/shdistribution$(…

深入了解代理IP常见协议:区别与选择

代理服务器在网络使用中扮演着重要的角色&#xff0c;是您设备和互联网之间的中间层。它不仅可以增强网络访问的安全性和隐私保护&#xff0c;还可以提供许多灵活的应用。使用代理时&#xff0c;不同的协议类型对数据交换具有不同的规则和特征。常见的代理协议包括HTTP代理、HT…