Android 天气APP(十一)未来七天的天气预报、逐小时预报、UI优化

时间:2022-07-25
本文章向大家介绍Android 天气APP(十一)未来七天的天气预报、逐小时预报、UI优化,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

上一篇:Android 天气APP(十)下拉刷新页面天气数据

前言

如果你看到这里那么你应该看过前面十篇文章了,这是第十一篇,其实写作的原意,并不是我想分这么多章节的,但是不得不分章节,我不能只考虑自己不考虑阅读的人,试问,我这里有一篇20万字的博客,你要不要看一下呢?你可能会望而却步吧,从而失去兴趣,故分章节,但请放心,我不是标题党,也不做无意义的分章节,标题肯定是要对应里面的内容的,现在有些博主写文章花里胡哨的,就靠标题吸引人,里面的内容都在胡扯,没有一点意义,题不对意,别人提问也不回复,这样就是不负责任,对此,我表示强烈的谴责和抗议。

正文

还记得之前注册这个和风天气的API吗?之前是用普通用户(作为白嫖党,如果不多搞一些,就亏了,所以我们要从普通用户升级到开发者,当然还是不要钱的,只不过拿到的数据会多一点,我们要的七天的天气预报就在开发者的版本里面,而且开发者的API访问是比普通用户要多的。当然你们要是有钱可以使用商业版,商业版的数据足够你开发一个商业级别的APP了,只不过商业版很贵就是了,我一个穷人用不起,当然我们也可以合作,你出钱,我出力,美滋滋),现在升级到开发者,点击和风天气登录,进入控制台

点击升级,会让你绑定手机号,输入验证码后下一步就是升级为开发者

作为开发者你就要对自己的APP负责了,所以就需要你的身份证号码和正反面照片了,还是应用的名称及应用的类型,相信你们也知道该怎么填,填完之后点击同意并变更

然后就会进入审核阶段,

审核的结果会发到你注册时的邮箱里面。慢慢等吧(建议你可以先把文章收藏,等你的审核通过之后继续看,有些文章,错过就不在了)。 反正你现在闲着也是闲着,来改UI吧,天气预报列表中的天气状态之前是用文字来描述的,现在改成用图标来描述,那么这个图标哪里来呢?羊毛出在羊身上,薅羊毛就要彻底一些,当然是去和风天气官网去拿图标了。

下载之后解压,你会看到很多图标,但是这些图标的颜色是蓝色的,而我希望是白色,这样才符合我这个APP的UI整体效果,所以还是要自己改一下图标的颜色,这么多图标,这也是个体力活啊,慢慢改吧。

打开你的PhotoShop,然后随便拖一个图标进去,比如这个图标。

颜色叠加

将默认的红色改成白色

然后点击确定,再点一次,回到PS主页面,可以看到就变成白色了

接下来保存图标,点击左上角的文件->存储为

格式保存为png格式,然后就是覆盖它原来的蓝色图标,然后一路保存,最后看到你的文件夹中的图标就变成白色的了。

好了,还有那么多图标呢,你慢慢改,不着急。磨刀不误砍柴工啊。 图标名中带“ n ”的是表示晚上,不带的就是白天的,你也可以改成白色的,并且在APP上增加现在是白天还是晚上的状态判断,也算是进一步优化,这个目前先不做。 Android不允许纯数字命名的图片,你可以把100.png改成icon_100.png。 所有图片都改好之后复制到你项目的mipmap-xhdpi文件夹下。 然后对照这个天气代码表来做判断显示 天气代码对照表

代码

中文

英文

图标

100

Sunny/Clear

100.png

101

多云

Cloudy

101.png

102

少云

Few Clouds

102.png

103

晴间多云

Partly Cloudy

103.png

104

Overcast

104.png

200

有风

Windy

200.png

201

平静

Calm

201.png

202

微风

Light Breeze

202.png

203

和风

Moderate/Gentle Breeze

203.png

204

清风

Fresh Breeze

204.png

205

强风/劲风

Strong Breeze

205.png

206

疾风

High Wind, Near Gale

206.png

207

大风

Gale

207.png

208

烈风

Strong Gale

208.png

209

风暴

Storm

209.png

210

狂爆风

Violent Storm

210.png

211

飓风

Hurricane

211.png

212

龙卷风

Tornado

212.png

213

热带风暴

Tropical Storm

213.png

300

阵雨

Shower Rain

300.png

301

强阵雨

Heavy Shower Rain

301.png

302

雷阵雨

Thundershower

302.png

303

强雷阵雨

Heavy Thunderstorm

303.png

304

雷阵雨伴有冰雹

Thundershower with hail

304.png

305

小雨

Light Rain

305.png

306

中雨

Moderate Rain

306.png

307

大雨

Heavy Rain

307.png

308

极端降雨

Extreme Rain

308.png

309

毛毛雨/细雨

Drizzle Rain

309.png

310

暴雨

Storm

310.png

311

大暴雨

Heavy Storm

311.png

312

特大暴雨

Severe Storm

312.png

313

冻雨

Freezing Rain

313.png

314

小到中雨

Light to moderate rain

314.png

315

中到大雨

Moderate to heavy rain

315.png

316

大到暴雨

Heavy rain to storm

316.png

317

暴雨到大暴雨

Storm to heavy storm

317.png

318

大暴雨到特大暴雨

Heavy to severe storm

318.png

399

Rain

399.png

400

小雪

Light Snow

400.png

401

中雪

Moderate Snow

401.png

402

大雪

Heavy Snow

402.png

403

暴雪

Snowstorm

403.png

404

雨夹雪

Sleet

404.png

405

雨雪天气

Rain And Snow

405.png

406

阵雨夹雪

Shower Snow

406.png

407

阵雪

Snow Flurry

407.png

408

小到中雪

Light to moderate snow

408.png

409

中到大雪

Moderate to heavy snow

409.png

410

大到暴雪

Heavy snow to snowstorm

410.png

499

Snow

499.png

500

薄雾

Mist

500.png

501

Foggy

501.png

502

Haze

502.png

503

扬沙

Sand

503.png

504

浮尘

Dust

504.png

507

沙尘暴

Duststorm

507.png

508

强沙尘暴

Sandstorm

508.png

509

浓雾

Dense fog

509.png

510

强浓雾

Strong fog

510.png

511

中度霾

Moderate haze

511.png

512

重度霾

Heavy haze

512.png

513

严重霾

Severe haze

513.png

514

大雾

Heavy fog

514.png

515

特强浓雾

Extra heavy fog

515.png

900

Hot

900.png

901

Cold

901.png

999

未知

Unknown

999.png

七天的天气预报和UI优化

在我修改图标颜色的过程中,发现有好几个天气代码的图标是一模一样的,所以代码中判断显示的时候会有几个状态码对应的图标一样,提前说明,不要见怪。 接下里就是修改天气预报列表的item的布局文件了。 item_weather_forecast_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:gravity="center_vertical"
        android:padding="@dimen/sp_12"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <!--日期-->
        <TextView
            android:id="@+id/tv_date"
            android:text="1234"
            android:textSize="@dimen/sp_14"
            android:textColor="#FFF"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"/>
        <!--天气描述  文字 隐藏-->
        <TextView
            android:visibility="gone"
            android:gravity="center"
            android:id="@+id/tv_info"
            android:textSize="@dimen/sp_14"
            android:textColor="#FFF"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"/>
        <!--天气描述  图标-->
        <ImageView
            android:id="@+id/iv_weather_state"
            android:background="@mipmap/icon_100"
            android:layout_width="30dp"
            android:layout_height="30dp"/>

        <!--最低温、最高温-->
        <TextView
            android:gravity="right"
            android:id="@+id/tv_low_and_height"
            android:textSize="@dimen/sp_14"
            android:textColor="#FFF"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</LinearLayout>

改动并不大,加了一个ImageView而已,然后在创建工具类 在utils包下创建一个WeatherUtil类

代码如下:

package com.llw.goodweather.utils;

import android.widget.ImageView;

import com.llw.goodweather.R;

/**
 * 天气工具类
 */
public class WeatherUtil {

    /**
     * 根据传入的状态码修改填入的天气图标
     * @param weatherStateIcon 显示的ImageView
     * @param code 天气状态码
     */
    public static void changeIcon(ImageView weatherStateIcon,int code){
        switch (code){
            case 100://晴
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_100);
                break;
            case 101://多云
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_101);
                break;
            case 102://少云
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_102);
                break;
            case 103://晴间多云
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_103);
                break;
            case 200://有风
            case 202://微风
            case 203://和风
            case 204://清风
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_200);//因为这几个状态的图标是一样的
                break;
            case 201://平静
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_201);
                break;
            case 205://强风/劲风
            case 206://疾风
            case 207://大风
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_205);//因为这几个状态的图标是一样的
                break;
            case 208://烈风
            case 209://风暴
            case 210://狂爆风
            case 211://飓风
            case 212://龙卷风
            case 213://热带风暴
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_208);//因为这几个状态的图标是一样的
                break;
            case 300://阵雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_300);
                break;
            case 301://强阵雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_301);
                break;
            case 302://雷阵雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_302);
                break;
            case 303://强雷阵雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_303);
                break;
            case 304://雷阵雨伴有冰雹
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_304);
                break;
            case 305://小雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_305);
                break;
            case 306://中雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_306);
                break;
            case 307://大雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_307);
                break;
            case 308://极端降雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_312);
                break;
            case 309://毛毛雨/细雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_309);
                break;
            case 310://暴雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_310);
                break;
            case 311://大暴雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_311);
                break;
            case 312://特大暴雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_312);
                break;
            case 313://冻雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_313);
                break;
            case 314://小到中雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_306);
                break;
            case 315://中到大雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_307);
                break;
            case 316://大到暴雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_310);
                break;
            case 317://大暴雨到特大暴雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_312);
                break;
            case 399://雨
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_399);
                break;
            case 400://小雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_400);
                break;
            case 401://中雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_401);
                break;
            case 402://大雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_402);
                break;
            case 403://暴雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_403);
                break;
            case 404://雨夹雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_404);
                break;
            case 405://雨雪天气
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_405);
                break;
            case 406://阵雨夹雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_406);
                break;
            case 407://阵雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_407);
                break;
            case 408://小到中雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_408);
                break;
            case 409://中到大雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_409);
                break;
            case 410://大到暴雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_410);
                break;
            case 499://雪
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_499);
                break;
            case 500://薄雾
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_500);
                break;
            case 501://雾
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_501);
                break;
            case 502://霾
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_502);
                break;
            case 503://扬沙
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_503);
                break;
            case 504://扬沙
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_504);
                break;
            case 507://沙尘暴
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_507);
                break;
            case 508://强沙尘暴
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_508);
                break;
            case 509://浓雾
            case 510://强浓雾
            case 514://大雾
            case 515://特强浓雾
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_509);
                break;
            case 511://中度霾
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_511);
                break;
            case 512://重度霾
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_512);
                break;
            case 513://严重霾
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_513);
                break;
            case 900://热
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_900);
                break;
            case 901://冷
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_901);
                break;
            case 999://未知
                weatherStateIcon.setBackgroundResource(R.mipmap.icon_999);
                break;
        }
    }
}

WeatherForecastAdapter.java中做判断显示图标,代码如下:

package com.llw.goodweather.adapter;

import android.widget.ImageView;

import androidx.annotation.Nullable;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.goodweather.R;
import com.llw.goodweather.bean.WeatherForecastResponse;
import com.llw.goodweather.utils.WeatherUtil;

import java.util.List;

/**
 * 天气预报列表展示适配器
 */
public class WeatherForecastAdapter extends BaseQuickAdapter<WeatherForecastResponse.HeWeather6Bean.DailyForecastBean, BaseViewHolder> {

    public WeatherForecastAdapter(int layoutResId, @Nullable List<WeatherForecastResponse.HeWeather6Bean.DailyForecastBean> data) {
        super(layoutResId, data);
    }

    @Override
    protected void convert(BaseViewHolder helper, WeatherForecastResponse.HeWeather6Bean.DailyForecastBean item) {
        helper.setText(R.id.tv_date, item.getDate())//日期
//                .setText(R.id.tv_info, item.getCond_txt_d())//天气
                .setText(R.id.tv_low_and_height, item.getTmp_min() + "/" + item.getTmp_max() + "℃");//最低温和最高温

        //天气状态图片
        ImageView weatherStateIcon = helper.getView(R.id.iv_weather_state);
        int code = Integer.parseInt(item.getCond_code_d());//获取天气状态码,根据状态码来显示图标
        WeatherUtil.changeIcon(weatherStateIcon,code);//调用工具类中写好的方法
    }
}

因为写作过程中,还有其他事情,所以并不是一蹴而就的,当我写适配器代码的时候就我的邮箱就已经收到通过审核的短信了,你如果没有收到也不要着急,只要资料没有问题,审核还是蛮快的,关键看审核的人员那个时候有没有帮你审核。现在我成为一个认证开发者了,那么可以直接运行一下。

再切换一个城市

从这个运行的效果图来看,完成了两件事,第一个就是未来七天的天气预报,这个只要你通过了审核,成为开发者,返回的数据自然就变成7天的,第二个就是UI优化,感觉图标显示还是比文字显示更好一些,这个就属于细节优化问题了,因为这个细节,你还是要做很多准备工作的。

逐小时预报和UI优化

https://free-api.heweather.net/s6/weather/hourly?location=%E7%A6%8F%E7%94%B0&key=3086e91d66c04ce588a7f538f917c7f4

访问测试地址,请以自己的Key去访问,返回的结果

在bean包下创建一个HourlyResponse.java,里面的代码如下:

package com.llw.goodweather.bean;


import java.util.List;

public class HourlyResponse {

    private List<HeWeather6Bean> HeWeather6;

    public List<HeWeather6Bean> getHeWeather6() {
        return HeWeather6;
    }

    public void setHeWeather6(List<HeWeather6Bean> HeWeather6) {
        this.HeWeather6 = HeWeather6;
    }

    public static class HeWeather6Bean {
        /**
         * basic : {"cid":"CN101280603","location":"福田","parent_city":"深圳","admin_area":"广东","cnty":"中国","lat":"22.5410099","lon":"114.05095673","tz":"+8.00"}
         * update : {"loc":"2020-04-28 19:56","utc":"2020-04-28 11:56"}
         * status : ok
         * hourly : [{"cloud":"43","cond_code":"101","cond_txt":"多云","dew":"19","hum":"71","pop":"0","pres":"1010","time":"2020-04-28 22:00","tmp":"23","wind_deg":"82","wind_dir":"东风","wind_sc":"1-2","wind_spd":"2"},{"cloud":"35","cond_code":"100","cond_txt":"晴","dew":"18","hum":"74","pop":"0","pres":"1011","time":"2020-04-29 01:00","tmp":"22","wind_deg":"14","wind_dir":"东北风","wind_sc":"1-2","wind_spd":"11"},{"cloud":"69","cond_code":"100","cond_txt":"晴","dew":"18","hum":"72","pop":"0","pres":"1011","time":"2020-04-29 04:00","tmp":"21","wind_deg":"43","wind_dir":"东北风","wind_sc":"1-2","wind_spd":"4"},{"cloud":"90","cond_code":"101","cond_txt":"多云","dew":"19","hum":"62","pop":"0","pres":"1008","time":"2020-04-29 07:00","tmp":"21","wind_deg":"53","wind_dir":"东北风","wind_sc":"1-2","wind_spd":"9"},{"cloud":"91","cond_code":"101","cond_txt":"多云","dew":"19","hum":"58","pop":"0","pres":"1008","time":"2020-04-29 10:00","tmp":"27","wind_deg":"45","wind_dir":"东北风","wind_sc":"1-2","wind_spd":"10"},{"cloud":"75","cond_code":"101","cond_txt":"多云","dew":"18","hum":"59","pop":"0","pres":"1009","time":"2020-04-29 13:00","tmp":"29","wind_deg":"32","wind_dir":"东北风","wind_sc":"1-2","wind_spd":"4"},{"cloud":"59","cond_code":"100","cond_txt":"晴","dew":"18","hum":"60","pop":"0","pres":"1009","time":"2020-04-29 16:00","tmp":"27","wind_deg":"50","wind_dir":"东北风","wind_sc":"1-2","wind_spd":"6"},{"cloud":"37","cond_code":"101","cond_txt":"多云","dew":"19","hum":"61","pop":"0","pres":"1008","time":"2020-04-29 19:00","tmp":"26","wind_deg":"-1","wind_dir":"无持续风向","wind_sc":"1-2","wind_spd":"2"}]
         */

        private BasicBean basic;
        private UpdateBean update;
        private String status;
        private List<HourlyBean> hourly;

        public BasicBean getBasic() {
            return basic;
        }

        public void setBasic(BasicBean basic) {
            this.basic = basic;
        }

        public UpdateBean getUpdate() {
            return update;
        }

        public void setUpdate(UpdateBean update) {
            this.update = update;
        }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public List<HourlyBean> getHourly() {
            return hourly;
        }

        public void setHourly(List<HourlyBean> hourly) {
            this.hourly = hourly;
        }

        public static class BasicBean {
            /**
             * cid : CN101280603
             * location : 福田
             * parent_city : 深圳
             * admin_area : 广东
             * cnty : 中国
             * lat : 22.5410099
             * lon : 114.05095673
             * tz : +8.00
             */

            private String cid;
            private String location;
            private String parent_city;
            private String admin_area;
            private String cnty;
            private String lat;
            private String lon;
            private String tz;

            public String getCid() {
                return cid;
            }

            public void setCid(String cid) {
                this.cid = cid;
            }

            public String getLocation() {
                return location;
            }

            public void setLocation(String location) {
                this.location = location;
            }

            public String getParent_city() {
                return parent_city;
            }

            public void setParent_city(String parent_city) {
                this.parent_city = parent_city;
            }

            public String getAdmin_area() {
                return admin_area;
            }

            public void setAdmin_area(String admin_area) {
                this.admin_area = admin_area;
            }

            public String getCnty() {
                return cnty;
            }

            public void setCnty(String cnty) {
                this.cnty = cnty;
            }

            public String getLat() {
                return lat;
            }

            public void setLat(String lat) {
                this.lat = lat;
            }

            public String getLon() {
                return lon;
            }

            public void setLon(String lon) {
                this.lon = lon;
            }

            public String getTz() {
                return tz;
            }

            public void setTz(String tz) {
                this.tz = tz;
            }
        }

        public static class UpdateBean {
            /**
             * loc : 2020-04-28 19:56
             * utc : 2020-04-28 11:56
             */

            private String loc;
            private String utc;

            public String getLoc() {
                return loc;
            }

            public void setLoc(String loc) {
                this.loc = loc;
            }

            public String getUtc() {
                return utc;
            }

            public void setUtc(String utc) {
                this.utc = utc;
            }
        }

        public static class HourlyBean {
            /**
             * cloud : 43
             * cond_code : 101
             * cond_txt : 多云
             * dew : 19
             * hum : 71
             * pop : 0
             * pres : 1010
             * time : 2020-04-28 22:00
             * tmp : 23
             * wind_deg : 82
             * wind_dir : 东风
             * wind_sc : 1-2
             * wind_spd : 2
             */

            private String cloud;
            private String cond_code;
            private String cond_txt;
            private String dew;
            private String hum;
            private String pop;
            private String pres;
            private String time;
            private String tmp;
            private String wind_deg;
            private String wind_dir;
            private String wind_sc;
            private String wind_spd;

            public String getCloud() {
                return cloud;
            }

            public void setCloud(String cloud) {
                this.cloud = cloud;
            }

            public String getCond_code() {
                return cond_code;
            }

            public void setCond_code(String cond_code) {
                this.cond_code = cond_code;
            }

            public String getCond_txt() {
                return cond_txt;
            }

            public void setCond_txt(String cond_txt) {
                this.cond_txt = cond_txt;
            }

            public String getDew() {
                return dew;
            }

            public void setDew(String dew) {
                this.dew = dew;
            }

            public String getHum() {
                return hum;
            }

            public void setHum(String hum) {
                this.hum = hum;
            }

            public String getPop() {
                return pop;
            }

            public void setPop(String pop) {
                this.pop = pop;
            }

            public String getPres() {
                return pres;
            }

            public void setPres(String pres) {
                this.pres = pres;
            }

            public String getTime() {
                return time;
            }

            public void setTime(String time) {
                this.time = time;
            }

            public String getTmp() {
                return tmp;
            }

            public void setTmp(String tmp) {
                this.tmp = tmp;
            }

            public String getWind_deg() {
                return wind_deg;
            }

            public void setWind_deg(String wind_deg) {
                this.wind_deg = wind_deg;
            }

            public String getWind_dir() {
                return wind_dir;
            }

            public void setWind_dir(String wind_dir) {
                this.wind_dir = wind_dir;
            }

            public String getWind_sc() {
                return wind_sc;
            }

            public void setWind_sc(String wind_sc) {
                this.wind_sc = wind_sc;
            }

            public String getWind_spd() {
                return wind_spd;
            }

            public void setWind_spd(String wind_spd) {
                this.wind_spd = wind_spd;
            }
        }
    }
}

页面渲染的数据从这些返回实体里面取,下一步,创建接口,打开ApiService.java 在里面增加

注意Key用自己的,然后创建订阅,打开WeatherContract.java

订阅方法

		/**
         * 逐小时预报
         * @param context
         * @param location
         */
        public void hourly(final Context context,String location){
            ApiService service = ServiceGenerator.createService(ApiService.class,0);
            service.getHourly(location).enqueue(new NetCallBack<HourlyResponse>() {
                @Override
                public void onSuccess(Call<HourlyResponse> call, Response<HourlyResponse> response) {
                    if(getView() != null){
                        getView().getHourlyResult(response);
                    }
                }

                @Override
                public void onFailed() {
                    if(getView() != null){
                        getView().getDataFailed();
                    }
                }
            });
        }

接口返回值

		//查询逐小时天气的数据返回
        void getHourlyResult(Response<HourlyResponse> response);

接下来就是MainActivity.java

代码如下:

	//逐小时天气预报返回
    @Override
    public void getHourlyResult(Response<HourlyResponse> response) {
        dismissLoadingDialog();//关闭弹窗
        if (("ok").equals(response.body().getHeWeather6().get(0).getStatus())) {

        } else {
            ToastUtils.showShortToast(context, response.body().getHeWeather6().get(0).getStatus());
        }
    }

需要在三个地方进行请求,拿到定位之后、下拉的时候、切换城市之后

通过断点查看到了返回的数据,这一步你可以跳过,不会有什么影响,往下走

现在数据已经拿到了,接下来就是数据的渲染了,依然使用列表来做显示,这里我们用横向的列表,摆放的位置就放在7天天气预报的上方,这样会比较合理。 接下来在layout下创建一个item_weather_hourly_list.xml文件,

这就是每一个item的显示效果,只不过背景是无色的,这里之所以放黑色背景,是在写布局的时候易于调整。

item_weather_hourly_list.xml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:padding="8dp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <!--时间-->
    <TextView
        android:id="@+id/tv_time"
        android:textColor="#FFF"
        android:text="上午10:00"
        android:textSize="14sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <!--气候图标-->
    <ImageView
        android:layout_marginTop="12dp"
        android:layout_marginBottom="8dp"
        android:id="@+id/iv_weather_state"
        android:background="@mipmap/icon_100"
        android:layout_width="30dp"
        android:layout_height="30dp"/>
    <!--温度-->
    <TextView
        android:textSize="20sp"
        android:id="@+id/tv_temperature"
        android:textColor="#FFF"
        android:text="25℃"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

然后在WeatherUtil.java中再增加一个方法showTimeInfo

	/**
     * 根据传入的时间显示时间段描述信息
     * @param timeData
     * @return
     */
    public static String showTimeInfo(String timeData){
        String timeInfo = null;
        int time = 0;
        time = Integer.parseInt(timeData.trim().substring(0,2));
        if (time >= 0 && time <= 6) {
            timeInfo = "凌晨";
        }else if (time > 6 && time <= 12) {
            timeInfo = "上午";
        }else if (time > 12 && time <= 13) {
            timeInfo = "中午";
        }else if (time > 13 && time <= 18) {
            timeInfo = "下午";
        } else if (time > 18 && time <= 24) {
            timeInfo = "晚上";
        } else {
            timeInfo = "未知";
        }
        return timeInfo;
    }

接下来在adapter包下创建一个WeatherHourlyAdapter.java

package com.llw.goodweather.adapter;

import android.widget.ImageView;

import androidx.annotation.Nullable;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.llw.goodweather.R;
import com.llw.goodweather.bean.HourlyResponse;
import com.llw.goodweather.utils.WeatherUtil;

import java.util.List;

public class WeatherHourlyAdapter extends BaseQuickAdapter<HourlyResponse.HeWeather6Bean.HourlyBean, BaseViewHolder> {

    public WeatherHourlyAdapter(int layoutResId, @Nullable List<HourlyResponse.HeWeather6Bean.HourlyBean> data) {
        super(layoutResId, data);
    }

    @Override
    protected void convert(BaseViewHolder helper, HourlyResponse.HeWeather6Bean.HourlyBean item) {
        //首先是对时间格式的处理,因为拿到的时间是  2020-04-28 22:00  要改成   晚上22:00
        //分两步,第一个是字符串的截取,第二个是时间段的判断返回文字描述
        String datetime = item.getTime();//赋值
        String time = datetime.substring(11);//截去前面的字符,保留后面所有的字符,就剩下 22:00
        helper.setText(R.id.tv_time,WeatherUtil.showTimeInfo(time)+time)//时间
                .setText(R.id.tv_temperature,item.getTmp()+"℃");//温度

        //天气状态图片
        ImageView weatherStateIcon = helper.getView(R.id.iv_weather_state);
        int code = Integer.parseInt(item.getCond_code());//获取天气状态码,根据状态码来显示图标
        WeatherUtil.changeIcon(weatherStateIcon,code);
    }

}

适配器写完了,接下来修改一下activity_main.xml布局文件

icon_weather_sun.png 上方是一个图标。因为是白色所以你看到不到而已

我改动之前的这个更新时间的布局,下方放了一个分割线和一个列表,列表用于显示逐小时天气、原来的天气预报列表增加了内边距 修改地方的代码如下:

							<!--上一次更新时间-->
                            <LinearLayout
                                android:paddingLeft="20dp"
                                android:paddingRight="20dp"
                                android:layout_marginTop="20dp"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content">
                                <TextView
                                    android:drawableLeft="@mipmap/icon_weather_sun"
                                    android:drawablePadding="4dp"
                                    android:text="Good Weather"
                                    android:textSize="@dimen/sp_12"
                                    android:textColor="#FFF"
                                    android:layout_width="wrap_content"
                                    android:layout_height="wrap_content"/>
                                <TextView
                                    android:gravity="right"
                                    android:id="@+id/tv_old_time"
                                    android:textColor="#FFF"
                                    android:text="上次更新时间:"
                                    android:textSize="@dimen/sp_12"
                                    android:layout_width="0dp"
                                    android:layout_weight="1"
                                    android:layout_height="wrap_content"/>
                            </LinearLayout>

                            <!--分隔线 增加UI效果-->
                            <View
                                android:layout_marginTop="8dp"
                                android:layout_marginLeft="20dp"
                                android:layout_marginRight="20dp"
                                android:layout_width="match_parent"
                                android:layout_height="1dp"
                                android:background="#FFF"
                                android:alpha="0.1"/>

                            <!--用于显示逐小时天气-->
                            <androidx.recyclerview.widget.RecyclerView
                                android:padding="12dp"
                                android:id="@+id/rv_hourly"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"/>

                            <!--用于显示天气预报数据-->
                            <androidx.recyclerview.widget.RecyclerView
                                android:paddingLeft="8dp"
                                android:paddingRight="8dp"
                                android:id="@+id/rv"
                                android:layout_width="match_parent"
                                android:layout_height="wrap_content"/>

接下来就是在MainActivity.java中渲染数据了。

初始列表和适配器

	List<HourlyResponse.HeWeather6Bean.HourlyBean> mListHourly;//初始化数据源 -> 逐小时天气预报
    WeatherHourlyAdapter mAdapterHourly;//初始化适配器 逐小时天气预报

改动的地方大概就这么多了,然后可以运行一下了。

运行效果图如下

这一篇文章就结束了,但是这个APP并没有结束,后续我有什么想法还会一直在里面加,当然各位有什么好的建议也可以评论或者私信我,写完才发现这篇文章也有34000多字,说短也不短了,如果你看了里面的内容不明白的话,就请从第一篇看起,你就一定知道是怎么回事了。 下一篇:Android 天气APP(十二)空气质量、UI优化调整