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

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

前言


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


正文


20200427110251886.png

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

20200427103243924.png


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

2020042711095136.png


20200427110926694.png


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

然后就会进入审核阶段,


20200427111706963.png

审核的结果会发到你注册时的邮箱里面。慢慢等吧(建议你可以先把文章收藏,等你的审核通过之后继续看,有些文章,错过就不在了)。


反正你现在闲着也是闲着,来改UI吧,天气预报列表中的天气状态之前是用文字来描述的,现在改成用图标来描述,那么这个图标哪里来呢?羊毛出在羊身上,薅羊毛就要彻底一些,当然是去和风天气官网去拿图标了。


202004271549325.png


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

20200427155413769.png


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


20200427155606212.png


颜色叠加


20200427155818963.png


将默认的红色改成白色


20200427155856222.png


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


20200427160020865.png


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


20200427160153367.png


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

20200427160306306.png

好了,还有那么多图标呢,你慢慢改,不着急。磨刀不误砍柴工啊。

图标名中带“ n ”的是表示晚上,不带的就是白天的,你也可以改成白色的,并且在APP上增加现在是白天还是晚上的状态判断,也算是进一步优化,这个目前先不做。


Android不允许纯数字命名的图片,你可以把100.png改成icon_100.png。

所有图片都改好之后复制到你项目的mipmap-xhdpi文件夹下。

然后对照这个天气代码表来做判断显示

天气代码对照表


4432e8a66f9d8e7fc375c6d9bd04397.png

ab85e8a14666df097089158e97b4f55.png

a4853d30b57859d726dd3afefee3c52.png

2a1bde30cec8b8bbc407a5180f12f42.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类


20200429113633484.png


代码如下:

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);//调用工具类中写好的方法
    }
}

20200427202254965.png



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


20200428154812423.png


再切换一个城市

20200428154908978.png


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


逐小时预报和UI优化


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

20200428200404961.png


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


2020042820072780.png


在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

在里面增加

20200428200952139.png

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


2020042820124385.png

20200428201324751.png


订阅方法


    /**
         * 逐小时预报
         * @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


20200428201503320.png


代码如下:

  //逐小时天气预报返回
    @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());
        }
    }


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


20200428201745799.png

20200428201820764.png


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


20200428202549327.png


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

接下来在layout下创建一个item_weather_hourly_list.xml文件,


20200429100842657.png


这就是每一个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布局文件


20200429142818640.png

icon_weather_sun.png


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

20200429143128990.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中渲染数据了。


20200429143610125.png


初始列表和适配器

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

20200429143737768.png

20200429143826147.png

20200429144120830.png


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


运行效果图如下

20200429144547848.png


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



相关文章
|
2天前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
2天前
|
编解码 Android开发
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
本文介绍了Android Studio中使用ConstraintLayout布局的方法,通过创建布局文件、设置控件约束等步骤,快速上手UI设计,并提供了一个TV Launcher界面布局的绘制示例。
11 1
|
3天前
|
API Android开发
Android P 性能优化:创建APP进程白名单,杀死白名单之外的进程
本文介绍了在Android P系统中通过创建应用进程白名单并杀死白名单之外的进程来优化性能的方法,包括设置权限、获取运行中的APP列表、配置白名单以及在应用启动时杀死非白名单进程的代码实现。
15 1
|
7天前
|
存储 分布式计算 供应链
Spark在供应链核算中应用问题之通过Spark UI进行任务优化如何解决
Spark在供应链核算中应用问题之通过Spark UI进行任务优化如何解决
|
7天前
|
IDE Java 开发工具
探索安卓开发之旅:打造你的第一款App
【8月更文挑战第24天】在这篇文章中,我们将一起踏上激动人心的安卓开发之旅。不论你是编程新手还是希望扩展技能的老手,本文将为你提供一份详尽指南,帮助你理解安卓开发的基础知识并实现你的第一个应用程序。从搭建开发环境到编写“Hello World”,每一步都将用浅显易懂的语言进行解释。那么,让我们开始吧!
|
10天前
|
API Android开发
Android项目架构设计问题之选择和使用合适的UI库如何解决
Android项目架构设计问题之选择和使用合适的UI库如何解决
21 0
|
18天前
|
开发工具 Android开发
|
18天前
|
Android开发
将AAB(Android App Bundle)转换为APK
将AAB(Android App Bundle)转换为APK
28 1
|
18天前
|
开发工具 Android开发
上架Google Play报错:For new apps, Android App Bundles must be signed with an RSA key.
上架Google Play报错:For new apps, Android App Bundles must be signed with an RSA key.
58 1
|
19天前
|
Android开发
Cannot create android app from an archive...containing both DEX and Java-bytecode content
Cannot create android app from an archive...containing both DEX and Java-bytecode content
16 2

热门文章

最新文章

下一篇
云函数