Android 天气APP(二十三)增加灾害预警、优化主页面UI

private List warning;

public String getCode() {

return code;

}

public void setCode(String code) {

this.code = code;

}

public String getUpdateTime() {

return updateTime;

}

public void setUpdateTime(String updateTime) {

this.updateTime = updateTime;

}

public String getFxLink() {

return fxLink;

}

public void setFxLink(String fxLink) {

this.fxLink = fxLink;

}

public ReferBean getRefer() {

return refer;

}

public void setRefer(ReferBean refer) {

this.refer = refer;

}

public List getWarning() {

return warning;

}

public void setWarning(List warning) {

this.warning = warning;

}

public static class ReferBean {

private List sources;

private List license;

public List getSources() {

return sources;

}

public void setSources(List sources) {

this.sources = sources;

}

public List getLicense() {

return license;

}

public void setLicense(List license) {

this.license = license;

}

}

public static class WarningBean {

/**

  • id : 23062241600000_20200813132751

  • sender : 肇源县气象局

  • pubTime : 2020-08-13T13:28+08:00

  • title : 肇源县气象局发布大风蓝色预警[IV级/一般]

  • startTime : 2020-08-13T13:30+08:00

  • endTime : 2020-08-14T13:30+08:00

  • status : active

  • level : 蓝色

  • type : 11B06

  • typeName : 大风

  • text : 肇源县气象台2020年8月13日13时28分发布大风蓝色预警信号:预计未来24小时肇源县受大风影响,平均风力可达5-6级,阵风可达7-8级,请有关单位和个人注意做好预防工作。防御指南:1.政府及相关部门按照职责做好防大风工作;2.关好门窗,加固围板、棚架、广告牌等易被风吹动的搭建物,妥善安置易受大风影响的室外物品,遮盖建筑物资;3.行人注意尽量少骑自行车,刮风时不要在广告牌、临时搭建物等下面逗留;4.有关部门和单位请注意森林、草原防火等防火,个人请注意室外和野外用火安全。

  • related :

*/

private String id;

private String sender;

private String pubTime;

private String title;

private String startTime;

private String endTime;

private String status;

private String level;

private String type;

private String typeName;

private String text;

private String related;

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getSender() {

return sender;

}

public void setSender(String sender) {

this.sender = sender;

}

public String getPubTime() {

return pubTime;

}

public void setPubTime(String pubTime) {

this.pubTime = pubTime;

}

public String getTitle() {

return title;

}

public void setTitle(String title) {

this.title = title;

}

public String getStartTime() {

return startTime;

}

public void setStartTime(String startTime) {

this.startTime = startTime;

}

public String getEndTime() {

return endTime;

}

public void setEndTime(String endTime) {

this.endTime = endTime;

}

public String getStatus() {

return status;

}

public void setStatus(String status) {

this.status = status;

}

public String getLevel() {

return level;

}

public void setLevel(String level) {

this.level = level;

}

public String getType() {

return type;

}

public void setType(String type) {

this.type = type;

}

public String getTypeName() {

return typeName;

}

public void setTypeName(String typeName) {

this.typeName = typeName;

}

public String getText() {

return text;

}

public void setText(String text) {

this.text = text;

}

public String getRelated() {

return related;

}

public void setRelated(String related) {

this.related = related;

}

}

}

2.新增API和方法


打开ApiService

在这里插入图片描述

新增了一个api接口,然后进入WeatherContract中,新增请求方法和返回

在这里插入图片描述

在这里插入图片描述

然后进入到MainActivity中增加

在这里插入图片描述

完成到这里,然后做数据的请求,在搜索城市的返回值中获取id,然后写入请求。

3.数据渲染


在这里插入图片描述

然后在返回的地方做数据的展示处理就可以了。先进入到activity_main.xml中,增加一个TextView,这个TextView做了一个简单的自定义修改,在mvplibrary下的view包下新建一个MarqueeTextView,然后继承TextView,代码如下:

package com.llw.mvplibrary.view;

import android.annotation.SuppressLint;

import android.content.Context;

import android.util.AttributeSet;

import android.widget.TextView;

import androidx.annotation.Nullable;

@SuppressLint(“AppCompatCustomView”)

public class MarqueeTextView extends TextView {

public MarqueeTextView(Context context) {

super(context);

}

public MarqueeTextView(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

}

public MarqueeTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public boolean isFocused() {

return true;

}

}

然后在布局中使用。

在这里插入图片描述

注意我放的位置,是在星期的上面,这个布局也要算在滑动的高度计算里面

<com.llw.mvplibrary.view.MarqueeTextView

android:id=“@+id/tv_warn”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_marginStart=“@dimen/dp_16”

android:layout_marginEnd=“@dimen/dp_16”

android:ellipsize=“marquee”

android:marqueeRepeatLimit=“marquee_forever”

android:paddingTop=“@dimen/dp_4”

android:paddingBottom=“@dimen/dp_4”

android:singleLine=“true”

android:textColor=“@color/white”

android:textSize=“@dimen/sp_12” />

android:marqueeRepeatLimit="marquee_forever"表示一直滚动

android:singleLine="true"表示单行

android:ellipsize="marquee"这里设置为超出文本后滚动显示

在MainActivity中声明

在这里插入图片描述

在返回值中做显示处理

在这里插入图片描述

这个灾害预警是存在没有数据的情况,所以没有数据的时候就隐藏掉这个TextView,这个我要说明一下不是所有城市都有灾害预警的,看你的运行了,如果没有数据你得到的返回就是这样的。

{

“code”: “200”,

“updateTime”: “2020-08-14T10:59+08:00”,

“fxLink”: “http://hfx.link/1u0z5”,

“warning”: [],

“refer”: {

“sources”: [

“12379”,

“Weather China”

],

“license”: [

“no commercial use”

]

}

}

这个我还特地问过和风那边是怎么回事,他们是这样回复我的。

如果你查询的城市预警信息返回为空,则代表这个城市当前没有预警信息。你也可以通过预警城市列表获得当前所有发生预警的城市id。即如果你想知道现在深圳市是否有预警,可以直接访问深圳市的预警信息,返回为空则当前无预警,或者访问预警城市列表,如果深圳城市id不在这个列表中,也代表当前深圳无预警。

他这里提到的预警城市列表,你可以用这个请求地址去获取,

https://devapi.heweather.net/v7/warning/list?range=cn&key=3086e91d66c04ce588a7f538f917c7f4

返回值就是当前有灾害预警的城市id列表,但是这个里面如果没有你当前定位到的城市的id,那你这个城市就没有灾害预警的信息,当然你想看数据的话,可以这样。下面我用这个101200106来演示这些数据。否则不够直观。

在这里插入图片描述

先这样赋值,然后你现在就可以运行了。

在这里插入图片描述

OK,效果就是上面那样,下面要做这个点击之后打开详情页面

4.灾害预报详情


在app下的ui包中新建一个WarnActivity,页面的布局如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:app=“http://schemas.android.com/apk/res-auto”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

android:background=“@drawable/img_6”

android:fitsSystemWindows=“true”

android:orientation=“vertical”

tools:context=“.ui.WarnActivity”>

<androidx.appcompat.widget.Toolbar

android:id=“@+id/toolbar”

android:layout_width=“match_parent”

android:layout_height=“?attr/actionBarSize”

app:contentInsetLeft=“@dimen/dp_16”

app:layout_constraintEnd_toEndOf=“parent”

app:layout_constraintLeft_toLeftOf=“parent”

app:layout_constraintTop_toTopOf=“parent”

app:navigationIcon=“@mipmap/icon_return_white”

app:popupTheme=“@style/AppTheme.PopupOverlay”>

<TextView

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_gravity=“center”

android:text=“灾害预警详情”

android:textColor=“@color/white”

android:textSize=“@dimen/sp_18” />

</androidx.appcompat.widget.Toolbar>

<androidx.recyclerview.widget.RecyclerView

android:paddingTop=“@dimen/dp_10”

android:id=“@+id/rv”

android:overScrollMode=“never”

android:layout_width=“match_parent”

android:layout_height=“match_parent”/>

布局很简单就是一个标题和一个列表。

然后创建item的布局,在layout下新建一个item_warn_list.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:layout_marginBottom=“@dimen/dp_10”

android:layout_marginLeft=“@dimen/dp_20”

android:layout_marginRight=“@dimen/dp_20”

android:background=“@drawable/shape_transparent_12”

android:gravity=“center_horizontal”

android:orientation=“vertical”

android:padding=“@dimen/dp_20”>

<TextView

android:id=“@+id/tv_city”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“城市”

android:textColor=“@color/white”

android:textSize=“@dimen/sp_16” />

<TextView

android:id=“@+id/tv_type_name_and_level”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_marginTop=“@dimen/dp_8”

android:text=“预警类型”

android:textColor=“@color/white”

android:textSize=“@dimen/sp_14” />

<TextView

android:id=“@+id/tv_content”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_marginTop=“@dimen/dp_12”

android:text=“预警详细内容”

android:textColor=“@color/white”

android:textSize=“@dimen/sp_14” />

<TextView

android:id=“@+id/tv_time”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:layout_marginTop=“@dimen/dp_8”

android:gravity=“right”

android:text=“预警发布时间”

android:textColor=“@color/white”

android:textSize=“@dimen/sp_12” />

也是比较的简单。

然后就要建适配器了,但是这个用内部类来解决好了。

在WarnActivity中,写入

/**

  • 内部适配器

*/

public class WarnAdapter extends BaseQuickAdapter<WarningResponse.WarningBean, BaseViewHolder> {

public WarnAdapter(int layoutResId, @Nullable List<WarningResponse.WarningBean> data) {

super(layoutResId, data);

}

@RequiresApi(api = Build.VERSION_CODES.O)

@Override

protected void convert(BaseViewHolder helper, WarningResponse.WarningBean item) {

TextView tvTime = helper.getView(R.id.tv_time);

String time = DateUtils.updateTime(item.getPubTime());

tvTime.setText(“预警发布时间:” + WeatherUtil.showTimeInfo(time) + time);

helper.setText(R.id.tv_city, item.getSender())//地区

.setText(R.id.tv_type_name_and_level,

item.getTypeName() + item.getLevel() + “预警”)//预警类型名称和等级

.setText(R.id.tv_content, item.getText());//预警详情内容

}

}

这段代码和onCreate是平级的。现在就要考虑数据的来源了,因为我们是在MainActivity中做请求的,但是详情数据在WarnActivity中显示,所以要先把数据传过来。

回到MainActivity,定义一个全局变量

private String warnBodyString = null;//灾害预警数据字符串

在这里插入图片描述

然后在返回值中将实体转换为JSON字符串,

在这里插入图片描述

再点击时传递到WarnActivity。

进入到WarnActivity,先继承BaseActivity,然后实现两个构造方法。将布局复制到getLayoutId的返回中,删掉onCreate方法。

然后在initData方法中实例化适配器,并填入数据

@RequiresApi(api = Build.VERSION_CODES.O)

@Override

public void initData(Bundle savedInstanceState) {

StatusBarUtil.transparencyBar(context);//透明状态栏

Back(toolbar);

WarningResponse data = new Gson().fromJson(getIntent().getStringExtra(“warnBodyString”), WarningResponse.class);

WarnAdapter mAdapter = new WarnAdapter(R.layout.item_warn_list,data.getWarning());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值