简易的安卓天气app(一)——解析Json数据、数据类封装
📌简易的安卓天气app(二)——适配器、每小时数据展示
简易的安卓天气app(三)——城市管理、数据库操作
简易的安卓天气app(四)——搜索城市、完善页面

需求

拒绝画饼,先讲需求,项目结构,整体思路,第一章我们只是封装了两个数据类WeatherBeanDayWeatherBean(此类存的是下图的data数据,是个JsonArray,里面包了JsonObject,7个表示7天,由于只需拿到当天数据,所以第0项就是当天详细天气),用来存放城市的当天天气,如果我们想要展示更精美的页面呢,或者说是展示更多的数据,比如,我们这里用RecyclerView展示一天中每个小时的天气,实现效果(若是想从当前时刻开始,获取小时温度,可自行实现,源码见页尾)
0

涉及内容

  • 获取网络数据
  • 数据实体类的封装
  • 异步获取网络数据
  • Gson工具类解析Json
  • 界面设计RecyclerView
  • 适配器adatper

项目结构

结构

界面设计

既然用到了RecyclerView,那么就离不开adapter,RecyclerView负责准备一个框框,adapter负责把什么数据传到框内,顾名思义适配器
详细讲解C一下,第一篇就是,讲的非常全面,附加地址Android RecyclerView最全使用详解
布局效果
4需要添加的RecyclerView

1
2
3
4
5
6
7
8
9
10
11
12
<LinearLayout
android:layout_width="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_height="100dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rlv_hour_weather"
android:background="@drawable/blackground"
android:alpha="0.75"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

id自定义名字,主要时在MainActivity里新增private RecyclerView rlvHourWeather;并findByView注册拿到之后就可以添加适配器了,想要哪个小页面传到这个RecyclerView中,,
每小时天气小界面:
7

6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="60dp"
android:layout_height="100dp"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:background="@mipmap/bg">

<TextView
android:id="@+id/tv_hours"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="8:00"
android:textColor="@color/white"
android:textSize="18sp" />
<ImageView
android:id="@+id/iv_weather"
android:layout_width="45dp"
android:layout_height="45dp"
android:src="@drawable/weather_yin" />

<TextView
android:id="@+id/tv_tem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textSize="19sp"
tools:text="31" />
</LinearLayout>

网络Json数据解析

第一篇我们已经从天气api接口拿到了json并成功解析,还封装了两个实体类
下面四从api拿到的数据,里面的json数据格式化之后的形式,首先为了下面的讲解代码流畅性,这次先从解析此api接口的json数据入手
1首先百度前往一个在线Json解析网站
https://www.json.cn/
或者是在Idea里新建个json后缀的文件,复制粘贴进去,格式化后就得到一层一层封装起来的json数据
或者前往客户端Android Studio寻找一个插件如下图第一个GsonFormat,详细用法自行C一下

在这里插入图片描述这里讲解就去了在线Json解析网站
https://www.json.cn/
复制粘贴进去Json数据,转义和格式化后得到,ps(自用的火狐浏览器挺好的,自带Json转换功能)
在这里插入图片描述第一篇文章已经写明,用到了第三方库Google的Gson工具,自动封装,两行代码完事,使用详情见第一篇文章,需要导包
3
想仔细学习,自己用JsonObject,JsonArray封装的,这篇文章不会讲太多,后面的文章会用到仔细封装,ps|小窍门(观察"[]"和"{}"你就会发现规律)
我们要得到每小时的数据,就要找一个对象,里面封装的是每小时的天气,就是说data数据0下标当天天气里还有一个对象,包了每个小时共24小时的详细数据,下面图片是解析

4所以,从此hours数据的结构得知有需要封装一个数据类,还是包在当日天气DayWeatherBean下的一个List。

每小时数据实体类封装

此处这个数据类就叫做HoursWearBean,那么先修改当日天气DayWeatherBean,添加一个
private List<HoursWeatherBean> hoursWeatherBeanList;属性,由于Gson会根据Json数据的属性名进行封装,所以就需要实现一个序列化接口implements Serializable,并添加注解
5
这样变量名就可以随便命名了
若是不想实现,就老老实实用private List<HoursWeatherBean> hours;,里面的变量名用hours命名之后就会发现可能报错,嘿嘿,每个小时数据里也有个hours
防止出错,属性可以都用一下注解,然后Get、Set修改一下,
接着就是每小时详细数据类的封装
HoursWeatherBean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

public class HoursWeatherBean implements Serializable {
@SerializedName("hours")
private String hours;

@SerializedName("wea_img")
private String weaImg;

@SerializedName("tem")
private String tem;

public String getHours() {
return hours;
}

public void setHours(String hours) {
this.hours = hours;
}

public String getWeaImg() {
return weaImg;
}

public void setWeaImg(String weaImg) {
this.weaImg = weaImg;
}

public String getTem() {
return tem;
}

public void setTem(String tem) {
this.tem = tem;
}

@Override
public String toString() {
return "HoursWeatherBean{" +
"hours='" + hours + '\'' +
", weaImg='" + weaImg + '\'' +
", tem='" + tem + '\'' +
'}';
}
}

适配器HourWeatherAdapter

  1. 继承自RecyclerView.Adapter,构造HourWeatherAdapter
1
2
3
4
5
6
private Context mContext;
private List<HoursWeatherBean> mHoursWeatherBeans;//写Activity时传进来的List,需要展示的数据集合
public HourWeatherAdapter(Context context, List<HoursWeatherBean> hoursWeatherBeans) {
mContext = context;
this.mHoursWeatherBeans = hoursWeatherBeans;
}
  1. 新建class类HourViewHolder
1
2
3
4
5
6
7
8
9
10
11
12
13
class HourViewHolder extends RecyclerView.ViewHolder {

TextView tvHours, tvTem;
ImageView ivWeather;

public HourViewHolder(@NonNull View itemView) {
super(itemView);
//绑定小页面的组件
tvHours = itemView.findViewById(R.id.tv_hours);
tvTem = itemView.findViewById(R.id.tv_tem);
ivWeather = itemView.findViewById(R.id.iv_weather);
}
}

8

  1. 然后重写三个方法

点击错误提示,快速重写三个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@NonNull
@Override
public HourViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//绑定View,每小时数据的小页面
View view = LayoutInflater.from(mContext).inflate(R.layout.hour_item_layout, parent, false);
HourViewHolder hourViewHolder = new HourViewHolder(view);
return hourViewHolder;
}

@Override
public void onBindViewHolder(@NonNull HourViewHolder holder, int position) {
HoursWeatherBean hoursweatherBean = mHoursWeatherBeans.get(position);
//根据位置position传值
holder.tvTem.setText(hoursweatherBean.getTem()+"℃");
holder.tvHours.setText(hoursweatherBean.getHours().substring(0,2)+":00");
holder.ivWeather.setImageResource(WeatherImgUtil.getImgResOfWeather(hoursweatherBean.getWeaImg()));
}

@Override
public int getItemCount() {
return (mHoursWeatherBeans == null) ? 0 : mHoursWeatherBeans.size();
}

MainActivity.java

接着就是拿到Json数据,封装称为数据类,我代码中直接Gson封装成WeatherBean,里面封装有List,而DayWeatherBean中又有List,一层一层包着,
当数据异步封装好后,
添加属性

1
2
3
private HourWeatherAdapter mHourAdapter;//适配器

private RecyclerView rlvHourWeather;//RecyclerView
1
2
3
4
5
6
7
8
9
/**
* 每小时温度
* dayWeather.getHoursWeatherBeanList()==>24小时数据List
*/
mHourAdapter = new HourWeatherAdapter(this, dayWeather.getHoursWeatherBeanList());
rlvHourWeather.setAdapter(mHourAdapter);
//数据水平布局
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
rlvHourWeather.setLayoutManager(layoutManager);

到此处就能完美展示每小时数据了,步骤在目录中,就是先设计界面,封装数据类,适配器,activity。代码行数有点小多,末尾附带源码
==源码地址==: