Android开发实战-项目学习笔记(2)

获取市信息

代码部分:

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.example.jnsyq.data.Sheng;
import com.example.jnsyq.data.Shi;
import com.example.jnsyq.data.Xian;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {

    //定义3个级别
    private static final int level_sheng = 0;
    private static final int level_shi = 1;
    private static final int level_xian = 2;

    private int level = 0; //变化

    //声明ListView
    private ListView listView;

    //声明省市县对应的列表
    private List<Sheng> ShengList = new ArrayList<>();
    private List<Shi> ShiList = new ArrayList<>();
    private List<Xian> XianList = new ArrayList<>();

    //声明省市县名称列表:数据源
    private List<String> nameList = new ArrayList<>();

    //创建适配器
    private ArrayAdapter<String> adapter;

    //全局的选中的省市县城市
    private Sheng s;
    private Shi shi;

    //消息处理
    //【内存泄漏】
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case 0:
                    //通知ListView数据更改
                    adapter.notifyDataSetChanged();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //调用初始化方法
        initListView();
        //联网初始化省信息
        getSheng();
    }

    /**
     * 新建初始化ListView方法
     */
    private void initListView() {
        //初始化ListView
        //在布局文件中找到该ListView
        listView = (ListView) findViewById(R.id.listview);

        //数据源、ListView、适配器实现绑定,数据和显示实时更新
        //初始化适配器,将适配器和数据源绑定在一起
        //this:上下文
        //simple_list_item_1:简单的布局
        //nameList:设置数据源
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, nameList);
        //绑定ListView和适配器,ListView设置适配器
        listView.setAdapter(adapter);
        //设置点击操作
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //通过点击的位置获取到点击的对象
                //如果当前级别是省级,那么获取省级对象,获取市级对象
                if (level == level_sheng) {
                    level = 1;
                    s = ShengList.get(position);
                    Log.d("MainActivity", "onItemClick: " + s.getName());
                    getShi();
                } else if (level == level_shi) {
                    shi = ShiList.get(position);
                    Log.d("MainActivity", "onItemClick: " + shi.getName());
                }
            }
        });
    }

    /**
     * 获取省一级的城市列表
     */
    private void getSheng() {
        //定义url,接口
        String url = "http://guolin.tech/api/china";
        //1.创建okhttp客户端
        OkHttpClient client = new OkHttpClient();
        //2.创建请求,构建请求参数
        Request request = new Request.Builder().url(url).build();
        //3.进行网络访问
        //new Callback():回调接口(线程)
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
//                e.printStackTrace();
                //如果访问失败,输出失败信息
                Log.d("MainActivity", "onFailure: 网络访问失败");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //将网络相应信息转换成字符串型
                //该操作只能执行一次
                String data = response.body().string();
//                String data1 = response.body().string(); //错误
                //输出日志信息
                Log.d("MainActivity", "onResponse: " + data);
                //解析数据,并生成数据类
                try {
                    //将json字符串转换为json数组
                    JSONArray shengs = new JSONArray(data); //需处理JSONException,未处理异常【用try/catch包括起来】
                    //遍历json数字,读取所有的json对象
                    for (int i = 0; i < shengs.length(); i++) {
                        //从json数组中读取json对象
                        JSONObject shengObject = shengs.getJSONObject(i);
                        //创建省一级城市对象
                        Sheng s = new Sheng();
                        //设置对应的值
                        s.setId(shengObject.getInt("id"));
                        s.setName(shengObject.getString("name"));
                        //将省对象添加到列表中
                        ShengList.add(s);
                        //将省名称添加到名称列表
                        nameList.add(s.getName());

                        //发送消息到Loop
                        //通过handleMessage进行消息处理
                        Message msg = new Message();
                        msg.what = 0; //消息id号
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取市级的城市列表
     * 法1:方法中缺少变量,可以直接传递进来
     */
//    private void getShi(int shengid) {
//        //url中省级id号是变量,url不完整
//        String url = "http://guolin.tech/api/china/" + shengid;
//    }

    /**
     * 获取市级的城市列表
     * 法2:①将被选中的省级城市定义为全部变量
     * ②在getShi方法中进行读取
     */
    private void getShi() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId();
        //1.创建okhttp客户端
        OkHttpClient client = new OkHttpClient();
        //2.创建请求,构建请求参数
        Request request = new Request.Builder().url(url).build();
        //3.进行网络访问
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Shi shi = new Shi();
                        shi.setId(jsonObject.getInt("id"));
                        shi.setName(jsonObject.getString("name"));
                        ShiList.add(shi);
                        nameList.add(shi.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

效果图:

Android开发实战-项目学习笔记(2)_第1张图片

获取省级信息

代码部分:

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.example.jnsyq.data.Sheng;
import com.example.jnsyq.data.Shi;
import com.example.jnsyq.data.Xian;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {

    //定义3个级别
    private static final int level_sheng = 0;
    private static final int level_shi = 1;
    private static final int level_xian = 2;

    private int level = 0; //变化

    //声明ListView
    private ListView listView;

    //声明省市县对应的列表
    private List<Sheng> ShengList = new ArrayList<>();
    private List<Shi> ShiList = new ArrayList<>();
    private List<Xian> XianList = new ArrayList<>();

    //声明省市县名称列表:数据源
    private List<String> nameList = new ArrayList<>();

    //创建适配器
    private ArrayAdapter<String> adapter;

    //全局的选中的省市县城市
    private Sheng s;
    private Shi shi;
    private Xian xian;

    //消息处理
    //【内存泄漏】
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case 0:
                    //通知ListView数据更改
                    adapter.notifyDataSetChanged();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //调用初始化方法
        initListView();
        //联网初始化省信息
        getSheng();
    }

    /**
     * 新建初始化ListView方法
     */
    private void initListView() {
        //初始化ListView
        //在布局文件中找到该ListView
        listView = (ListView) findViewById(R.id.listview);

        //数据源、ListView、适配器实现绑定,数据和显示实时更新
        //初始化适配器,将适配器和数据源绑定在一起
        //this:上下文
        //simple_list_item_1:简单的布局
        //nameList:设置数据源
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, nameList);
        //绑定ListView和适配器,ListView设置适配器
        listView.setAdapter(adapter);
        //设置点击操作
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //通过点击的位置获取到点击的对象
                //如果当前级别是省级,那么获取省级对象,获取市级对象
                if (level == level_sheng) {
                    level = level_shi;
                    s = ShengList.get(position);
                    Log.d("MainActivity", "onItemClick: " + s.getName());
                    getShi();
                } else if (level == level_shi) {
                    level = level_xian;
                    shi = ShiList.get(position);
                    Log.d("MainActivity", "onItemClick: " + shi.getName());
                    getXian();
                } else if (level == level_xian) {
                    xian = XianList.get(position);
                    Log.d("MainActivity", "onItemClick: " + xian.getName());
                }
            }
        });
    }

    /**
     * 获取省一级的城市列表
     */
    private void getSheng() {
        //定义url,接口
        String url = "http://guolin.tech/api/china";
        //1.创建okhttp客户端
        OkHttpClient client = new OkHttpClient();
        //2.创建请求,构建请求参数
        Request request = new Request.Builder().url(url).build();
        //3.进行网络访问
        //new Callback():回调接口(线程)
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
//                e.printStackTrace();
                //如果访问失败,输出失败信息
                Log.d("MainActivity", "onFailure: 网络访问失败");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //将网络相应信息转换成字符串型
                //该操作只能执行一次
                String data = response.body().string();
//                String data1 = response.body().string(); //错误
                //输出日志信息
                Log.d("MainActivity", "onResponse: " + data);
                //解析数据,并生成数据类
                try {
                    //将json字符串转换为json数组
                    JSONArray shengs = new JSONArray(data); //需处理JSONException,未处理异常【用try/catch包括起来】
                    //遍历json数字,读取所有的json对象
                    for (int i = 0; i < shengs.length(); i++) {
                        //从json数组中读取json对象
                        JSONObject shengObject = shengs.getJSONObject(i);
                        //创建省一级城市对象
                        Sheng s = new Sheng();
                        //设置对应的值
                        s.setId(shengObject.getInt("id"));
                        s.setName(shengObject.getString("name"));
                        //将省对象添加到列表中
                        ShengList.add(s);
                        //将省名称添加到名称列表
                        nameList.add(s.getName());

                        //发送消息到Loop
                        //通过handleMessage进行消息处理
                        Message msg = new Message();
                        msg.what = 0; //消息id号
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取市级的城市列表
     * 法1:方法中缺少变量,可以直接传递进来
     */
//    private void getShi(int shengid) {
//        //url中省级id号是变量,url不完整
//        String url = "http://guolin.tech/api/china/" + shengid;
//    }

    /**
     * 获取市级的城市列表
     * 法2:①将被选中的省级城市定义为全部变量
     * ②在getShi方法中进行读取
     */
    private void getShi() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId();
        //1.创建okhttp客户端
        OkHttpClient client = new OkHttpClient();
        //2.创建请求,构建请求参数
        Request request = new Request.Builder().url(url).build();
        //3.进行网络访问
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Shi shi = new Shi();
                        shi.setId(jsonObject.getInt("id"));
                        shi.setName(jsonObject.getString("name"));
                        ShiList.add(shi);
                        nameList.add(shi.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取县级的城市列表
     */
    private void getXian() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId() + "/" + shi.getId();
        //1.创建okhttp客户端
        OkHttpClient client = new OkHttpClient();
        //2.创建请求,构建请求参数
        Request request = new Request.Builder().url(url).build();
        //3.进行网络访问
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Xian xian = new Xian();
                        xian.setId(jsonObject.getInt("id"));
                        xian.setName(jsonObject.getString("name"));
                        xian.setWeather_id(jsonObject.getString("weather_id"));
                        XianList.add(xian);
                        nameList.add(xian.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

效果图:

Android开发实战-项目学习笔记(2)_第2张图片

省市县返回问题

选错了省市县以后退回上一级别选择
注:通过重写actionbar实现返回的功能
在这里插入图片描述

第一步:

res/values中,修改styles.xml代码,效果如下:
Android开发实战-项目学习笔记(2)_第3张图片
Android开发实战-项目学习笔记(2)_第4张图片
Android开发实战-项目学习笔记(2)_第5张图片

第二步:

res/drawable中图片,插入修改xml

ic_back.png在这里插入图片描述

ic_home.png

在这里插入图片描述


<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:orientation="vertical"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary">

        <Button
            android:id="@+id/back"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_centerVertical="true"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dp"
            android:layout_marginStart="10dp"
            android:background="@drawable/ic_back"
            android:layout_alignParentStart="true" />

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textSize="20sp"
            android:textColor="#fff"
            tools:text="山东"/>

    RelativeLayout>

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

LinearLayout>
  • layout_centerVertical:上下居中,垂直居中
  • layout_alignParentLeft:左边,居左
  • layout_alignParentStart:开始,根据设置不同读取文字方向,其作用不同
    • 从左向右,start代表左边
    • 从右往左,start代表右边
  • layout_marginLeft:左边间隔
  • layout_marginStart:开始间隔
  • layout_centerInParent:在父组件布局中居中
  • tools:占位,程序运行时不会显示出来

效果图:

Android开发实战-项目学习笔记(2)_第6张图片

第三步:

声明控件

标题自定义

主要代码,截图:
Android开发实战-项目学习笔记(2)_第7张图片

Button返回

主要代码,截图:
Android开发实战-项目学习笔记(2)_第8张图片

问题:

网络访问

省级 -> 市级 -> 网络访问 需要
市级 -> 省级 -> 网络访问 不需要
修改代码,截图:
Android开发实战-项目学习笔记(2)_第9张图片
Android开发实战-项目学习笔记(2)_第10张图片
注:清空

反复重写

MainActivity.java中网络访问省市县三步走相同,故可以提取出来,新建工具类,方法调用

修改前:

MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.example.jnsyq.data.Sheng;
import com.example.jnsyq.data.Shi;
import com.example.jnsyq.data.Xian;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {

    //定义3个级别
    private static final int level_sheng = 0;
    private static final int level_shi = 1;
    private static final int level_xian = 2;

    private int level = 0; //变化

    //声明控件
    private ListView listView; //ListView
    private Button buttonBack; //Button
    private TextView title; //TextView

    //声明省市县对应的列表
    private List<Sheng> ShengList = new ArrayList<>();
    private List<Shi> ShiList = new ArrayList<>();
    private List<Xian> XianList = new ArrayList<>();

    //声明省市县名称列表:数据源
    private List<String> nameList = new ArrayList<>();

    //创建适配器
    private ArrayAdapter<String> adapter;

    //全局的选中的省市县城市
    private Sheng s;
    private Shi shi;
    private Xian xian;

    //消息处理
    //【内存泄漏】
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case 0:
                    //通知ListView数据更改
                    adapter.notifyDataSetChanged();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buttonBack = findViewById(R.id.back);
        //button添加点击操作
        buttonBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //点击操作,首先判断当前级别
                //如果当前处于县级,返回市级
                if (level == level_xian) {
                    level = level_shi;
                    //显示上一级省名称
                    title.setText(s.getName());
                    //法1:重新获取一次市级列表
//                    getShi();
                    //法2:直接遍历市级列表
                    //将所有的市级名称填到homelist中
                    nameList.clear();
                    //ShiList.for回车,自动出
                    for (Shi shi1 : ShiList) {
                        nameList.add(shi1.getName());
                        adapter.notifyDataSetChanged();
                    }
                } else if (level == level_shi) {
                    level = level_sheng;
                    title.setText("中国");
                    for (Sheng sheng1 : ShengList) {
                        nameList.add(sheng1.getName());
                        adapter.notifyDataSetChanged();
                    }
                }
            }
        });

        title = findViewById(R.id.title);
        title.setText("中国");

        //调用初始化方法
        initListView();
        //联网初始化省信息
        getSheng();
    }

    /**
     * 新建初始化ListView方法
     */
    private void initListView() {
        //初始化ListView
        //在布局文件中找到该ListView
        listView = (ListView) findViewById(R.id.listview);

        //数据源、ListView、适配器实现绑定,数据和显示实时更新
        //初始化适配器,将适配器和数据源绑定在一起
        //this:上下文
        //simple_list_item_1:简单的布局
        //nameList:设置数据源
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, nameList);
        //绑定ListView和适配器,ListView设置适配器
        listView.setAdapter(adapter);
        //设置点击操作
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //通过点击的位置获取到点击的对象
                //如果当前级别是省级,那么获取省级对象,获取市级对象
                if (level == level_sheng) {
                    level = level_shi;
                    s = ShengList.get(position);
                    //点击的哪个省,那么title显示该省名称
                    title.setText(s.getName());
                    Log.d("MainActivity", "onItemClick: " + s.getName());
                    getShi();
                } else if (level == level_shi) {
                    level = level_xian;
                    shi = ShiList.get(position);
                    //点击的哪个市,那么title显示该市名称
                    title.setText(shi.getName());
                    Log.d("MainActivity", "onItemClick: " + shi.getName());
                    getXian();
                } else if (level == level_xian) {
                    xian = XianList.get(position);
                    Log.d("MainActivity", "onItemClick: " + xian.getName());
                }
            }
        });
    }

    /**
     * 获取省一级的城市列表
     */
    private void getSheng() {
        //定义url,接口
        String url = "http://guolin.tech/api/china";
        //1.创建okhttp客户端
        OkHttpClient client = new OkHttpClient();
        //2.创建请求,构建请求参数
        Request request = new Request.Builder().url(url).build();
        //3.进行网络访问
        //new Callback():回调接口(线程)
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
//                e.printStackTrace();
                //如果访问失败,输出失败信息
                Log.d("MainActivity", "onFailure: 网络访问失败");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //将网络相应信息转换成字符串型
                //该操作只能执行一次
                String data = response.body().string();
//                String data1 = response.body().string(); //错误
                //输出日志信息
                Log.d("MainActivity", "onResponse: " + data);
                //解析数据,并生成数据类
                try {
                    nameList.clear();
                    ShengList.clear();
                    //将json字符串转换为json数组
                    JSONArray shengs = new JSONArray(data); //需处理JSONException,未处理异常【用try/catch包括起来】
                    //遍历json数字,读取所有的json对象
                    for (int i = 0; i < shengs.length(); i++) {
                        //从json数组中读取json对象
                        JSONObject shengObject = shengs.getJSONObject(i);
                        //创建省一级城市对象
                        Sheng s = new Sheng();
                        //设置对应的值
                        s.setId(shengObject.getInt("id"));
                        s.setName(shengObject.getString("name"));
                        //将省对象添加到列表中
                        ShengList.add(s);
                        //将省名称添加到名称列表
                        nameList.add(s.getName());

                        //发送消息到Loop
                        //通过handleMessage进行消息处理
                        Message msg = new Message();
                        msg.what = 0; //消息id号
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取市级的城市列表
     * 法1:方法中缺少变量,可以直接传递进来
     */
//    private void getShi(int shengid) {
//        //url中省级id号是变量,url不完整
//        String url = "http://guolin.tech/api/china/" + shengid;
//    }

    /**
     * 获取市级的城市列表
     * 法2:①将被选中的省级城市定义为全部变量
     * ②在getShi方法中进行读取
     */
    private void getShi() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId();
        //1.创建okhttp客户端
        OkHttpClient client = new OkHttpClient();
        //2.创建请求,构建请求参数
        Request request = new Request.Builder().url(url).build();
        //3.进行网络访问
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    ShiList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Shi shi = new Shi();
                        shi.setId(jsonObject.getInt("id"));
                        shi.setName(jsonObject.getString("name"));
                        ShiList.add(shi);
                        nameList.add(shi.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取县级的城市列表
     */
    private void getXian() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId() + "/" + shi.getId();
        //1.创建okhttp客户端
        OkHttpClient client = new OkHttpClient();
        //2.创建请求,构建请求参数
        Request request = new Request.Builder().url(url).build();
        //3.进行网络访问
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    XianList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Xian xian = new Xian();
                        xian.setId(jsonObject.getInt("id"));
                        xian.setName(jsonObject.getString("name"));
                        xian.setWeather_id(jsonObject.getString("weather_id"));
                        XianList.add(xian);
                        nameList.add(xian.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

修改后:

新建Uitils工具类,截图和代码部分如下:
Android开发实战-项目学习笔记(2)_第11张图片

import okhttp3.OkHttpClient;
import okhttp3.Request;
/**
 * 工具类
 */
public class HttpUtils {

    /**
     * 网络访问三步走
     * #注意:static 静态方法,只和类有关系,和对象无关
     * @param url 要访问的网络地址
     * @param callback 回调
     */
    public static void sendOkhttpRequest(String url, okhttp3.Callback callback) {
        //1.创建okhttp客户端
        OkHttpClient client = new OkHttpClient();
        //2.创建请求,拼接请求参数
        Request request = new Request.Builder().url(url).build();
        //3.进行网络访问
        //new Callback():回调接口(线程)
        client.newCall(request).enqueue(callback);
    }

}

MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.example.jnsyq.data.Sheng;
import com.example.jnsyq.data.Shi;
import com.example.jnsyq.data.Xian;
import com.example.jnsyq.utils.HttpUtils;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {

    //定义3个级别
    /* static:静态;final:常量 */
    private static final int level_sheng = 0;
    private static final int level_shi = 1;
    private static final int level_xian = 2;
    private int level = 0; //变化

    //声明控件
    private ListView listView; //ListView
    private Button buttonBack; //Button
    private TextView title; //TextView

    //声明省市县对应的列表
    private List<Sheng> ShengList = new ArrayList<>();
    private List<Shi> ShiList = new ArrayList<>();
    private List<Xian> XianList = new ArrayList<>();
    //声明省市县名称列表:数据源
    private List<String> nameList = new ArrayList<>();

    //创建适配器
    private ArrayAdapter<String> adapter;

    //全局的选中的省市县城市
    private Sheng s;
    private Shi shi;
    private Xian xian;

    //消息处理loop
    //【内存泄漏】
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case 0:
                    //通知ListView数据更改
                    adapter.notifyDataSetChanged();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buttonBack = findViewById(R.id.back);
        //button添加点击操作
        buttonBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //点击操作,首先判断当前级别
                //如果当前处于县级,返回市级
                if (level == level_xian) {
                    level = level_shi;
                    //显示上一级省名称
                    title.setText(s.getName());
                    //法1:重新获取一次市级列表
//                    getShi();
                    //法2:直接遍历市级列表
                    //将所有的市级名称填到homelist中
                    nameList.clear();
                    //ShiList.for回车,自动出
                    for (Shi shi1 : ShiList) {
                        nameList.add(shi1.getName());
                        adapter.notifyDataSetChanged();
                    }
                } else if (level == level_shi) {
                    level = level_sheng;
                    title.setText("中国");
                    nameList.clear();
                    for (Sheng sheng1 : ShengList) {
                        nameList.add(sheng1.getName());
                        adapter.notifyDataSetChanged();
                    }
                }
            }
        });

        title = findViewById(R.id.title);
        title.setText("中国");

        //调用初始化方法
        initListView();
        //联网初始化省信息
        getSheng();
    }

    /**
     * 新建初始化ListView方法
     */
    private void initListView() {
        //初始化ListView
        //在布局文件中找到该ListView
        listView = (ListView) findViewById(R.id.listview);

        //数据源、ListView、适配器实现绑定,数据和显示实时更新
        //初始化适配器,将适配器和数据源绑定在一起
        //this:上下文
        //simple_list_item_1:简单的布局
        //nameList:设置数据源
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, nameList);
        //绑定ListView和适配器,ListView设置适配器
        listView.setAdapter(adapter);
        //设置点击操作
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //通过点击的位置获取到点击的对象
                //如果当前级别是省级,那么获取省级对象,获取市级对象
                if (level == level_sheng) {
                    level = level_shi;
                    s = ShengList.get(position);
                    //点击的哪个省,那么title显示该省名称
                    title.setText(s.getName());
                    Log.d("MainActivity", "onItemClick: " + s.getName());
                    getShi();
                } else if (level == level_shi) {
                    level = level_xian;
                    shi = ShiList.get(position);
                    //点击的哪个市,那么title显示该市名称
                    title.setText(shi.getName());
                    Log.d("MainActivity", "onItemClick: " + shi.getName());
                    getXian();
                } else if (level == level_xian) {
                    xian = XianList.get(position);
                    Log.d("MainActivity", "onItemClick: " + xian.getName());
                    //TODO:跳转到天气显示界面
                }
            }
        });
    }

    /**
     * 获取省一级的城市列表
     */
    private void getSheng() {
        //定义url,接口
        String url = "http://guolin.tech/api/china";

        //#注意:正常情况下,先创建对象,再调用方法
//        HttpUtil httpUtil = new HttpUtils();
//        httpUtil.sendOkhttpRequest();

        //每次网络访问时,直接调用sendOkhttpRequest即可
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
//                e.printStackTrace();
                //如果访问失败,输出失败信息
                Log.d("MainActivity", "onFailure: 网络访问失败");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //将网络相应信息转换成字符串型
                //该操作只能执行一次
                String data = response.body().string();
//                String data1 = response.body().string(); //错误
                //输出日志信息
                Log.d("MainActivity", "onResponse: " + data);
                //解析数据,并生成数据类
                try {
                    nameList.clear();
                    ShengList.clear();
                    //将json字符串转换为json数组
                    JSONArray shengs = new JSONArray(data); //需处理JSONException,未处理异常【用try/catch包括起来】
                    //遍历json数字,读取所有的json对象
                    for (int i = 0; i < shengs.length(); i++) {
                        //从json数组中读取json对象
                        JSONObject shengObject = shengs.getJSONObject(i);
                        //创建省一级城市对象
                        Sheng s = new Sheng();
                        //设置对应的值
                        s.setId(shengObject.getInt("id"));
                        s.setName(shengObject.getString("name"));
                        //将省对象添加到列表中
                        ShengList.add(s);
                        //将省名称添加到名称列表
                        nameList.add(s.getName());

                        //发送消息到Loop
                        //通过handleMessage进行消息处理
                        Message msg = new Message();
                        msg.what = 0; //消息id号
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取市级的城市列表
     * 法1:方法中缺少变量,可以直接传递进来
     */
//    private void getShi(int shengid) {
//        //url中省级id号是变量,url不完整
//        String url = "http://guolin.tech/api/china/" + shengid;
//    }

    /**
     * 获取市级的城市列表
     * 法2:①将被选中的省级城市定义为全部变量
     * ②在getShi方法中进行读取
     */
    private void getShi() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId();
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    ShiList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Shi shi = new Shi();
                        shi.setId(jsonObject.getInt("id"));
                        shi.setName(jsonObject.getString("name"));
                        ShiList.add(shi);
                        nameList.add(shi.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取县级的城市列表
     */
    private void getXian() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId() + "/" + shi.getId();
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    XianList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Xian xian = new Xian();
                        xian.setId(jsonObject.getInt("id"));
                        xian.setName(jsonObject.getString("name"));
                        xian.setWeather_id(jsonObject.getString("weather_id"));
                        XianList.add(xian);
                        nameList.add(xian.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

其中,TODO表示对未完成情况做标记
Android开发实战-项目学习笔记(2)_第12张图片

效果图:

省级:

Android开发实战-项目学习笔记(2)_第13张图片

市级:

Android开发实战-项目学习笔记(2)_第14张图片

县级:

Android开发实战-项目学习笔记(2)_第15张图片

控制台

在这里插入图片描述

显示地名和时间

第一步:

api:http://guolin.tech/api/weather?cityid=CN101190401
创建数据类:使用gsonformat创建实时天气的数据类

  • 右键单击,选择Generate...

Android开发实战-项目学习笔记(2)_第16张图片

  • 选择GsonFormat

Android开发实战-项目学习笔记(2)_第17张图片效果图如下:
Android开发实战-项目学习笔记(2)_第18张图片

  • https://www.tianqiapi.com/api?version=v6&appid=55233412&appsecret=2Mm5xcPA&cityid=CN101121101,复制该网址数据,点击Format

Android开发实战-项目学习笔记(2)_第19张图片
效果图如下:
Android开发实战-项目学习笔记(2)_第20张图片

  • 效果如图,点击OK

Android开发实战-项目学习笔记(2)_第21张图片

代码部分:

package com.example.jnsyq.data;
/**
 * 实时天气数据类
 */
public class inTimeWeather {

    /**
     * cityid : 101250101
     * date : 2020-08-14
     * week : 星期五
     * update_time : 2020-08-14 19:23:53
     * city : 长沙
     * cityEn : changsha
     * country : 中国
     * countryEn : China
     * wea : 晴
     * wea_img : qing
     * tem : 33
     * tem1 : 34
     * tem2 : 27
     * win : 南风
     * win_speed : 2级
     * win_meter : 小于12km/h
     * humidity : 54%
     * visibility : 35km
     * pressure : 1000
     * air : 30
     * air_pm25 : 30
     * air_level : 优
     * air_tips : 空气很好,可以外出活动,呼吸新鲜空气,拥抱大自然!
     * alarm : {"alarm_type":"","alarm_level":"","alarm_content":""}
     */

    private String cityid;
    private String date;
    private String week;
    private String update_time;
    private String city;
    private String cityEn;
    private String country;
    private String countryEn;
    private String wea;
    private String wea_img;
    private String tem;
    private String tem1;
    private String tem2;
    private String win;
    private String win_speed;
    private String win_meter;
    private String humidity;
    private String visibility;
    private String pressure;
    private String air;
    private String air_pm25;
    private String air_level;
    private String air_tips;
    private AlarmBean alarm;

    public String getCityid() {
        return cityid;
    }

    public void setCityid(String cityid) {
        this.cityid = cityid;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getWeek() {
        return week;
    }

    public void setWeek(String week) {
        this.week = week;
    }

    public String getUpdate_time() {
        return update_time;
    }

    public void setUpdate_time(String update_time) {
        this.update_time = update_time;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCityEn() {
        return cityEn;
    }

    public void setCityEn(String cityEn) {
        this.cityEn = cityEn;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getCountryEn() {
        return countryEn;
    }

    public void setCountryEn(String countryEn) {
        this.countryEn = countryEn;
    }

    public String getWea() {
        return wea;
    }

    public void setWea(String wea) {
        this.wea = wea;
    }

    public String getWea_img() {
        return wea_img;
    }

    public void setWea_img(String wea_img) {
        this.wea_img = wea_img;
    }

    public String getTem() {
        return tem;
    }

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

    public String getTem1() {
        return tem1;
    }

    public void setTem1(String tem1) {
        this.tem1 = tem1;
    }

    public String getTem2() {
        return tem2;
    }

    public void setTem2(String tem2) {
        this.tem2 = tem2;
    }

    public String getWin() {
        return win;
    }

    public void setWin(String win) {
        this.win = win;
    }

    public String getWin_speed() {
        return win_speed;
    }

    public void setWin_speed(String win_speed) {
        this.win_speed = win_speed;
    }

    public String getWin_meter() {
        return win_meter;
    }

    public void setWin_meter(String win_meter) {
        this.win_meter = win_meter;
    }

    public String getHumidity() {
        return humidity;
    }

    public void setHumidity(String humidity) {
        this.humidity = humidity;
    }

    public String getVisibility() {
        return visibility;
    }

    public void setVisibility(String visibility) {
        this.visibility = visibility;
    }

    public String getPressure() {
        return pressure;
    }

    public void setPressure(String pressure) {
        this.pressure = pressure;
    }

    public String getAir() {
        return air;
    }

    public void setAir(String air) {
        this.air = air;
    }

    public String getAir_pm25() {
        return air_pm25;
    }

    public void setAir_pm25(String air_pm25) {
        this.air_pm25 = air_pm25;
    }

    public String getAir_level() {
        return air_level;
    }

    public void setAir_level(String air_level) {
        this.air_level = air_level;
    }

    public String getAir_tips() {
        return air_tips;
    }

    public void setAir_tips(String air_tips) {
        this.air_tips = air_tips;
    }

    public AlarmBean getAlarm() {
        return alarm;
    }

    public void setAlarm(AlarmBean alarm) {
        this.alarm = alarm;
    }

    public static class AlarmBean {
        /**
         * alarm_type :
         * alarm_level :
         * alarm_content :
         */

        private String alarm_type;
        private String alarm_level;
        private String alarm_content;

        public String getAlarm_type() {
            return alarm_type;
        }

        public void setAlarm_type(String alarm_type) {
            this.alarm_type = alarm_type;
        }

        public String getAlarm_level() {
            return alarm_level;
        }

        public void setAlarm_level(String alarm_level) {
            this.alarm_level = alarm_level;
        }

        public String getAlarm_content() {
            return alarm_content;
        }

        public void setAlarm_content(String alarm_content) {
            this.alarm_content = alarm_content;
        }
    }
    
}

注:{}表示json对象(Object)对应java里面的类,当使用AlarmBean的时候,set和get给的是AlarmBean

第二步:

创建天气显示Activity
new Empty Activity,修改名称,效果如下:
Android开发实战-项目学习笔记(2)_第22张图片
Android开发实战-项目学习笔记(2)_第23张图片
MainActivity.java中添加代码,如下:
在这里插入图片描述

第三步:

添加gson包,在build.gradle中添加代码,如下:

implementation "com.google.code.gson:gson:2.8.6"

注意:点击Sync Now
在WeatherActivity.java中,使用gson获取数据,代码如下:
Android开发实战-项目学习笔记(2)_第24张图片

第四步:

activity_weather.xml


<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:orientation="vertical"
    tools:context=".WeatherActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary">

        <TextView
            android:id="@+id/title_city"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textSize="20sp"
            android:textColor="#fff"
            tools:text="济南"/>

        <TextView
            android:id="@+id/title_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:textSize="16sp"
            android:textColor="#fff"
            android:layout_marginRight="12dp"
            android:layout_marginEnd="12dp"
            tools:text="15:00" />

    RelativeLayout>

LinearLayout>

注意:textSize设置大小时,尽量使用4的倍数

效果图:

Android开发实战-项目学习笔记(2)_第25张图片

第四步:

完善MainActivity.java【修改省级中变量的名称,jsonArray】和WeatherActivity.java,启动WeatherAcitivity的方法有两种

法1:

MainActivity.java
Android开发实战-项目学习笔记(2)_第26张图片
WeatherActivity.java
Android开发实战-项目学习笔记(2)_第27张图片

法2:

注意:该方法的作用为避免传输数据类型排错
MainActivity.java
在这里插入图片描述
WeatherActivity.java
Android开发实战-项目学习笔记(2)_第28张图片

问题:

NullPointerException

变量被声明,没有初始化,内存中不存在被调用导致空指针异常
Android开发实战-项目学习笔记(2)_第29张图片
Android开发实战-项目学习笔记(2)_第30张图片
Android开发实战-项目学习笔记(2)_第31张图片

代码部分:

MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.example.jnsyq.data.Sheng;
import com.example.jnsyq.data.Shi;
import com.example.jnsyq.data.Xian;
import com.example.jnsyq.utils.HttpUtils;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {

    //定义3个级别
    /* static:静态;final:常量 */
    private static final int level_sheng = 0;
    private static final int level_shi = 1;
    private static final int level_xian = 2;
    private int level = 0; //变化

    //声明控件
    private ListView listView; //ListView
    private Button buttonBack; //Button
    private TextView title; //TextView

    //声明省市县对应的列表
    private List<Sheng> ShengList = new ArrayList<>();
    private List<Shi> ShiList = new ArrayList<>();
    private List<Xian> XianList = new ArrayList<>();
    //声明省市县名称列表:数据源
    private List<String> nameList = new ArrayList<>();

    //创建适配器
    private ArrayAdapter<String> adapter;

    //全局的选中的省市县城市
    private Sheng s;
    private Shi shi;
    private Xian xian;

    //消息处理loop
    //【内存泄漏】
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case 0:
                    //通知ListView数据更改
                    adapter.notifyDataSetChanged();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buttonBack = findViewById(R.id.back);
        //button添加点击操作
        buttonBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //点击操作,首先判断当前级别
                //如果当前处于县级,返回市级
                if (level == level_xian) {
                    level = level_shi;
                    //显示上一级省名称
                    title.setText(s.getName());
                    //法1:重新获取一次市级列表
//                    getShi();
                    //法2:直接遍历市级列表
                    //将所有的市级名称填到homelist中
                    nameList.clear();
                    //ShiList.for回车,自动出
                    for (Shi shi1 : ShiList) {
                        nameList.add(shi1.getName());
                        adapter.notifyDataSetChanged();
                    }
                } else if (level == level_shi) {
                    level = level_sheng;
                    title.setText("中国");
                    nameList.clear();
                    for (Sheng sheng1 : ShengList) {
                        nameList.add(sheng1.getName());
                        adapter.notifyDataSetChanged();
                    }
                }
            }
        });

        title = findViewById(R.id.title);
        title.setText("中国");

        //调用初始化方法
        initListView();
        //联网初始化省信息
        getSheng();
    }

    /**
     * 新建初始化ListView方法
     */
    private void initListView() {
        //初始化ListView
        //在布局文件中找到该ListView
        listView = (ListView) findViewById(R.id.listview);

        //数据源、ListView、适配器实现绑定,数据和显示实时更新
        //初始化适配器,将适配器和数据源绑定在一起
        //this:上下文
        //simple_list_item_1:简单的布局
        //nameList:设置数据源
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, nameList);
        //绑定ListView和适配器,ListView设置适配器
        listView.setAdapter(adapter);
        //设置点击操作
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //通过点击的位置获取到点击的对象
                //如果当前级别是省级,那么获取省级对象,获取市级对象
                if (level == level_sheng) {
                    level = level_shi;
                    s = ShengList.get(position);
                    //点击的哪个省,那么title显示该省名称
                    title.setText(s.getName());
                    Log.d("MainActivity", "onItemClick: " + s.getName());
                    getShi();
                } else if (level == level_shi) {
                    level = level_xian;
                    shi = ShiList.get(position);
                    //点击的哪个市,那么title显示该市名称
                    title.setText(shi.getName());
                    Log.d("MainActivity", "onItemClick: " + shi.getName());
                    getXian();
                } else if (level == level_xian) {
                    xian = XianList.get(position);
                    Log.d("MainActivity", "onItemClick: " + xian.getName());

                    //跳转到天气显示界面
                    //法1:
//                    Intent intent = new Intent(MainActivity.this, WeatherActivity.class);
//                    //传递cityid到下一个活动
//                    //将weatherid传递到下一个活动,作为cityid参数
//                    intent.putExtra("cityid", xian.getWeather_id());
//                    startActivity(intent);
                    //法2:启动活动的方法
                    WeatherActivity.actionStart(MainActivity.this, xian.getWeather_id());
                }
            }
        });
    }

    /**
     * 获取省一级的城市列表
     */
    private void getSheng() {
        //定义url,接口
        String url = "http://guolin.tech/api/china";

        //#注意:正常情况下,先创建对象,再调用方法
//        HttpUtil httpUtil = new HttpUtils();
//        httpUtil.sendOkhttpRequest();

        //每次网络访问时,直接调用sendOkhttpRequest即可
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
//                e.printStackTrace();
                //如果访问失败,输出失败信息
                Log.d("MainActivity", "onFailure: 网络访问失败");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //将网络相应信息转换成字符串型
                //该操作只能执行一次
                String data = response.body().string();
//                String data1 = response.body().string(); //错误
                //输出日志信息
                Log.d("MainActivity", "onResponse: " + data);
                //解析数据,并生成数据类
                try {
                    nameList.clear();
                    ShengList.clear();
                    //将json字符串转换为json数组
                    JSONArray jsonArray = new JSONArray(data); //需处理JSONException,未处理异常【用try/catch包括起来】
                    //遍历json数字,读取所有的json对象
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //从json数组中读取json对象
                        JSONObject shengObject = jsonArray.getJSONObject(i);
                        //创建省一级城市对象
                        Sheng s = new Sheng();
                        //设置对应的值
                        s.setId(shengObject.getInt("id"));
                        s.setName(shengObject.getString("name"));
                        //将省对象添加到列表中
                        ShengList.add(s);
                        //将省名称添加到名称列表
                        nameList.add(s.getName());

                        //发送消息到Loop
                        //通过handleMessage进行消息处理
                        Message msg = new Message();
                        msg.what = 0; //消息id号
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取市级的城市列表
     * 法1:方法中缺少变量,可以直接传递进来
     */
//    private void getShi(int shengid) {
//        //url中省级id号是变量,url不完整
//        String url = "http://guolin.tech/api/china/" + shengid;
//    }

    /**
     * 获取市级的城市列表
     * 法2:①将被选中的省级城市定义为全部变量
     * ②在getShi方法中进行读取
     */
    private void getShi() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId();
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    ShiList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Shi shi = new Shi();
                        shi.setId(jsonObject.getInt("id"));
                        shi.setName(jsonObject.getString("name"));
                        ShiList.add(shi);
                        nameList.add(shi.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取县级的城市列表
     */
    private void getXian() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId() + "/" + shi.getId();
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    XianList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Xian xian = new Xian();
                        xian.setId(jsonObject.getInt("id"));
                        xian.setName(jsonObject.getString("name"));
                        xian.setWeather_id(jsonObject.getString("weather_id"));
                        XianList.add(xian);
                        nameList.add(xian.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

WeatherActivity.java

import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
import com.example.jnsyq.data.InTimeWeather;
import com.example.jnsyq.utils.HttpUtils;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class WeatherActivity extends AppCompatActivity {

    private InTimeWeather inTimeWeather;

    //声明控件
    private TextView titleCity;
    private TextView titleTime;

    private String cityid; //private protected public(默认:protected)

    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case 0:
                    //调用更新ui方法
                    updateUi();
                    break;
                default:
                    break;
            }
        }
    };

    public static void actionStart(Context context, String cityid) {
        Intent intent = new Intent(context, WeatherActivity.class);
        intent.putExtra("cityid", cityid);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_weather);

        //从布局中找到控件
        titleCity = findViewById(R.id.title_city);
        titleTime = findViewById(R.id.title_time);

        //获取意图
        Intent intent = getIntent();
        //获取上一个活动传递劲来的数据
        //初始化cityid的值
        cityid = intent.getStringExtra("cityid");

        //调用该方法获取数据
        getWeatherInfo();
    }

    private void updateUi() {
        //设置对应值
        titleCity.setText(inTimeWeather.getCity());
        titleTime.setText(inTimeWeather.getUpdate_time().split(" ")[1]);
    }

    /**
     * 创建获取天气信息的方法
     */
    private void getWeatherInfo() {
        //通过调用api获取天气信息
        //直接通过ip地址进行天气信息获取
        //cityid:变量,由上一个活动传递进来
        String url = "https://www.tianqiapi.com/api?version=v6&appid=55233412&appsecret=2Mm5xcPA&cityid=" + cityid.replace("CN", "");
        //获取网络信息
        //网络访问需要新开线程进行执行,不影响主线程
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //读取返回的数据
                String data = response.body().string();
                //新建gson对象
                Gson gson = new Gson();
                //解析json数据,初始化inTimeWeather
                inTimeWeather = gson.fromJson(data, InTimeWeather.class); //json格式化

                //初始化天气以后,发送消息,更新ui界面
                Message msg = new Message();
                msg.what = 0;
                handler.sendMessage(msg);
            }
        });
    }

}

效果图:

在县级下选择桦南,效果如下:
Android开发实战-项目学习笔记(2)_第32张图片

城市id存储

  • sharedpreferences
  • sqlite(数据库)

cityid:101120901

注意:使用sharedpreferences,使得每次打开app的时候查看上次是否选择城市,如果选择了,无需再选
MainActivity.java
Android开发实战-项目学习笔记(2)_第33张图片
Android开发实战-项目学习笔记(2)_第34张图片

代码部分:

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import com.example.jnsyq.data.Sheng;
import com.example.jnsyq.data.Shi;
import com.example.jnsyq.data.Xian;
import com.example.jnsyq.utils.HttpUtils;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {

    //定义3个级别
    /* static:静态;final:常量 */
    private static final int level_sheng = 0;
    private static final int level_shi = 1;
    private static final int level_xian = 2;
    private int level = 0; //变化

    //声明控件
    private ListView listView; //ListView
    private Button buttonBack; //Button
    private TextView title; //TextView

    //声明省市县对应的列表
    private List<Sheng> ShengList = new ArrayList<>();
    private List<Shi> ShiList = new ArrayList<>();
    private List<Xian> XianList = new ArrayList<>();
    //声明省市县名称列表:数据源
    private List<String> nameList = new ArrayList<>();

    //创建适配器
    private ArrayAdapter<String> adapter;

    //全局的选中的省市县城市
    private Sheng s;
    private Shi shi;
    private Xian xian;

    //消息处理loop
    //【内存泄漏】
    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case 0:
                    //通知ListView数据更改
                    adapter.notifyDataSetChanged();
                    break;
                default:
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //创建sharedPreferences对象
        SharedPreferences sharedPreferences = getSharedPreferences("data", MODE_PRIVATE);
        String cityid = sharedPreferences.getString("cityid", "");
        //如果读取到了cityid,cityid长度大于0
        if (cityid.length() > 0) {
            WeatherActivity.actionStart(MainActivity.this, cityid);
        }

        buttonBack = findViewById(R.id.back);
        //button添加点击操作
        buttonBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //点击操作,首先判断当前级别
                //如果当前处于县级,返回市级
                if (level == level_xian) {
                    level = level_shi;
                    //显示上一级省名称
                    title.setText(s.getName());
                    //法1:重新获取一次市级列表
//                    getShi();
                    //法2:直接遍历市级列表
                    //将所有的市级名称填到homelist中
                    nameList.clear();
                    //ShiList.for回车,自动出
                    for (Shi shi1 : ShiList) {
                        nameList.add(shi1.getName());
                        adapter.notifyDataSetChanged();
                    }
                } else if (level == level_shi) {
                    level = level_sheng;
                    title.setText("中国");
                    nameList.clear();
                    for (Sheng sheng1 : ShengList) {
                        nameList.add(sheng1.getName());
                        adapter.notifyDataSetChanged();
                    }
                }
            }
        });

        title = findViewById(R.id.title);
        title.setText("中国");

        //调用初始化方法
        initListView();
        //联网初始化省信息
        getSheng();
    }

    /**
     * 新建初始化ListView方法
     */
    private void initListView() {
        //初始化ListView
        //在布局文件中找到该ListView
        listView = (ListView) findViewById(R.id.listview);

        //数据源、ListView、适配器实现绑定,数据和显示实时更新
        //初始化适配器,将适配器和数据源绑定在一起
        //this:上下文
        //simple_list_item_1:简单的布局
        //nameList:设置数据源
        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, nameList);
        //绑定ListView和适配器,ListView设置适配器
        listView.setAdapter(adapter);
        //设置点击操作
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                //通过点击的位置获取到点击的对象
                //如果当前级别是省级,那么获取省级对象,获取市级对象
                if (level == level_sheng) {
                    level = level_shi;
                    s = ShengList.get(position);
                    //点击的哪个省,那么title显示该省名称
                    title.setText(s.getName());
                    Log.d("MainActivity", "onItemClick: " + s.getName());
                    getShi();
                } else if (level == level_shi) {
                    level = level_xian;
                    shi = ShiList.get(position);
                    //点击的哪个市,那么title显示该市名称
                    title.setText(shi.getName());
                    Log.d("MainActivity", "onItemClick: " + shi.getName());
                    getXian();
                } else if (level == level_xian) {
                    xian = XianList.get(position);
                    Log.d("MainActivity", "onItemClick: " + xian.getName());

                    //选择city以后,在跳转到天气活动之前进行cityid存储
                    //获取edit对象,编辑sharedpreferences文件
                    SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
                    //将cityid存储到文件中
                    editor.putString("cityid", xian.getWeather_id());
                    //进行确定,应用,保存
                    editor.apply();

                    //跳转到天气显示界面
                    //法1:
//                    Intent intent = new Intent(MainActivity.this, WeatherActivity.class);
//                    //传递cityid到下一个活动
//                    //将weatherid传递到下一个活动,作为cityid参数
//                    intent.putExtra("cityid", xian.getWeather_id());
//                    startActivity(intent);
                    //法2:启动活动的方法
                    WeatherActivity.actionStart(MainActivity.this, xian.getWeather_id());
                }
            }
        });
    }

    /**
     * 获取省一级的城市列表
     */
    private void getSheng() {
        //定义url,接口
        String url = "http://guolin.tech/api/china";

        //#注意:正常情况下,先创建对象,再调用方法
//        HttpUtil httpUtil = new HttpUtils();
//        httpUtil.sendOkhttpRequest();

        //每次网络访问时,直接调用sendOkhttpRequest即可
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
//                e.printStackTrace();
                //如果访问失败,输出失败信息
                Log.d("MainActivity", "onFailure: 网络访问失败");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //将网络相应信息转换成字符串型
                //该操作只能执行一次
                String data = response.body().string();
//                String data1 = response.body().string(); //错误
                //输出日志信息
                Log.d("MainActivity", "onResponse: " + data);
                //解析数据,并生成数据类
                try {
                    nameList.clear();
                    ShengList.clear();
                    //将json字符串转换为json数组
                    JSONArray jsonArray = new JSONArray(data); //需处理JSONException,未处理异常【用try/catch包括起来】
                    //遍历json数字,读取所有的json对象
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //从json数组中读取json对象
                        JSONObject shengObject = jsonArray.getJSONObject(i);
                        //创建省一级城市对象
                        Sheng s = new Sheng();
                        //设置对应的值
                        s.setId(shengObject.getInt("id"));
                        s.setName(shengObject.getString("name"));
                        //将省对象添加到列表中
                        ShengList.add(s);
                        //将省名称添加到名称列表
                        nameList.add(s.getName());

                        //发送消息到Loop
                        //通过handleMessage进行消息处理
                        Message msg = new Message();
                        msg.what = 0; //消息id号
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取市级的城市列表
     * 法1:方法中缺少变量,可以直接传递进来
     */
//    private void getShi(int shengid) {
//        //url中省级id号是变量,url不完整
//        String url = "http://guolin.tech/api/china/" + shengid;
//    }

    /**
     * 获取市级的城市列表
     * 法2:①将被选中的省级城市定义为全部变量
     * ②在getShi方法中进行读取
     */
    private void getShi() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId();
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    ShiList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Shi shi = new Shi();
                        shi.setId(jsonObject.getInt("id"));
                        shi.setName(jsonObject.getString("name"));
                        ShiList.add(shi);
                        nameList.add(shi.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 获取县级的城市列表
     */
    private void getXian() {
        //定义url,接口
        String url = "http://guolin.tech/api/china/" + s.getId() + "/" + shi.getId();
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                try {
                    //清空nameList,准备存放数据
                    nameList.clear();
                    XianList.clear();
                    JSONArray jsonArray = new JSONArray(data);
                    for (int i = 0; i < jsonArray.length(); i++) {
                        //获取第i个位置的json对象
                        JSONObject jsonObject = jsonArray.getJSONObject(i);
                        Xian xian = new Xian();
                        xian.setId(jsonObject.getInt("id"));
                        xian.setName(jsonObject.getString("name"));
                        xian.setWeather_id(jsonObject.getString("weather_id"));
                        XianList.add(xian);
                        nameList.add(xian.getName());

                        Message msg = new Message();
                        msg.what = 0;
                        handler.sendMessage(msg);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

获取并显示实时天气【7天天气】

第一步:

activity_weather.xml


<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:orientation="vertical"
    tools:context=".WeatherActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary">

        <TextView
            android:id="@+id/title_city"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textSize="20sp"
            android:textColor="#fff"
            tools:text="济南"/>

        <TextView
            android:id="@+id/title_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:textSize="16sp"
            android:textColor="#fff"
            android:layout_marginRight="12dp"
            android:layout_marginEnd="12dp"
            tools:text="15:00" />

    RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="32dp">

        <TextView
            android:id="@+id/degree"
            android:textColor="#000"
            android:textSize="60sp"
            tools:text="20℃"
            android:layout_gravity="end"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/weather_info"
            android:textColor="#000"
            android:textSize="20sp"
            tools:text=""
            android:layout_gravity="end"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    LinearLayout>

LinearLayout>

效果图:

Android开发实战-项目学习笔记(2)_第35张图片

第二步:

WeatherActivity.java
Android开发实战-项目学习笔记(2)_第36张图片
Android开发实战-项目学习笔记(2)_第37张图片
Android开发实战-项目学习笔记(2)_第38张图片

效果图:

Android开发实战-项目学习笔记(2)_第39张图片

第三步:

api:http://www.tianqiapi.com/api?version=v1&appid=72458447&appsecret=E2P8xV9n
新建七日天气数据类Forecast.java,代码如下:

import java.util.List;
/**
 *七日天气数据类
 */
public class Forecast {

    /**
     * cityid : 101250101
     * update_time : 2020-08-15 06:52:20
     * city : 长沙
     * cityEn : changsha
     * country : 中国
     * countryEn : China
     * data : [{"day":"15日(今天)","date":"2020-08-15","week":"星期六","wea":"晴","wea_img":"qing","air":22,"humidity":76,"air_level":"优","air_tips":"空气很好,可以外出活动,呼吸新鲜空气,拥抱大自然!","alarm":{"alarm_type":"","alarm_level":"","alarm_content":""},"tem1":"36℃","tem2":"27℃","tem":"29℃","win":["南风","南风"],"win_speed":"3-4级转<3级","hours":[{"day":"15日08时","wea":"多云","tem":"29℃","win":"南风","win_speed":"3-4级"},{"day":"15日11时","wea":"晴","tem":"32℃","win":"南风","win_speed":"3-4级"},{"day":"15日14时","wea":"晴","tem":"34℃","win":"南风","win_speed":"3-4级"},{"day":"15日17时","wea":"晴","tem":"35℃","win":"南风","win_speed":"<3级"},{"day":"15日20时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"15日23时","wea":"晴","tem":"29℃","win":"南风","win_speed":"<3级"},{"day":"16日02时","wea":"晴","tem":"28℃","win":"南风","win_speed":"<3级"},{"day":"16日05时","wea":"晴","tem":"27℃","win":"南风","win_speed":"<3级"}],"index":[{"title":"中国人民保险
中暑指数","level":"较易中暑","desc":"长时间户外工作的你要适当调整作业时间,备好遮阳设施,及时补充盐分。"},{"title":"<\/em><\/em><\/em>","level":null,"desc":"天热风大,可选择低强度运动。"},{"title":"健臻·血糖指数","level":"易波动","desc":"气温高,血糖易波动,注意防暑降温。"},{"title":"穿衣指数","level":"炎热","desc":"建议穿短衫、短裤等清凉夏季服装。"},{"title":"洗车指数","level":"较不宜","desc":"风力较大,洗车后会蒙上灰尘。"},{"title":"紫外线指数","level":"很强","desc":"涂擦SPF20以上,PA++护肤品,避强光。"}]},{"day":"16日(明天)","date":"2020-08-16","week":"星期日","wea":"晴","wea_img":"qing","tem1":"36℃","tem2":"27℃","tem":"30℃","win":["南风","南风"],"win_speed":"<3级","hours":[{"day":"16日08时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"16日11时","wea":"晴","tem":"33℃","win":"南风","win_speed":"<3级"},{"day":"16日14时","wea":"晴","tem":"35℃","win":"南风","win_speed":"<3级"},{"day":"16日17时","wea":"晴","tem":"35℃","win":"南风","win_speed":"<3级"},{"day":"16日20时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"16日23时","wea":"晴","tem":"28℃","win":"南风","win_speed":"<3级"},{"day":"17日02时","wea":"晴","tem":"27℃","win":"南风","win_speed":"<3级"},{"day":"17日05时","wea":"晴","tem":"27℃","win":"南风","win_speed":"<3级"}],"index":[{"title":"中国人民保险
中暑指数","level":"较易中暑","desc":"炎炎夏日里,出行尽量穿浅色或素色服装。"},{"title":"<\/em><\/em><\/em>","level":null,"desc":"天气有点热,运动多补水。"},{"title":"健臻·血糖指数","level":"易波动","desc":"气温高,血糖易波动,注意防暑降温。"},{"title":"穿衣指数","level":"炎热","desc":"建议穿短衫、短裤等清凉夏季服装。"},{"title":"洗车指数","level":"适宜","desc":"天气较好,适合擦洗汽车。"},{"title":"紫外线指数","level":"很强","desc":"涂擦SPF20以上,PA++护肤品,避强光。"}]},{"day":"17日(后天)","date":"2020-08-17","week":"星期一","wea":"晴","wea_img":"qing","tem1":"36℃","tem2":"27℃","tem":"29℃","win":["南风","南风"],"win_speed":"<3级","hours":[{"day":"17日08时","wea":"晴","tem":"29℃","win":"南风","win_speed":"<3级"},{"day":"17日11时","wea":"晴","tem":"33℃","win":"南风","win_speed":"<3级"},{"day":"17日14时","wea":"晴","tem":"35℃","win":"南风","win_speed":"<3级"},{"day":"17日17时","wea":"晴","tem":"35℃","win":"南风","win_speed":"<3级"},{"day":"17日20时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"17日23时","wea":"晴","tem":"29℃","win":"南风","win_speed":"<3级"},{"day":"18日02时","wea":"晴","tem":"28℃","win":"南风","win_speed":"<3级"},{"day":"18日05时","wea":"晴","tem":"27℃","win":"南风","win_speed":"<3级"}],"index":[{"title":"中国人民保险
中暑指数","level":"易中暑","desc":"酷暑炎炎,尽量避免在上午10点至下午2点外出。"},{"title":"<\/em><\/em><\/em>","level":null,"desc":"天气有点热,运动多补水。"},{"title":"健臻·血糖指数","level":"易波动","desc":"气温高,血糖易波动,注意防暑降温。"},{"title":"穿衣指数","level":"炎热","desc":"建议穿短衫、短裤等清凉夏季服装。"},{"title":"洗车指数","level":"适宜","desc":"天气较好,适合擦洗汽车。"},{"title":"紫外线指数","level":"很强","desc":"涂擦SPF20以上,PA++护肤品,避强光。"}]},{"day":"18日(周二)","date":"2020-08-18","week":"星期二","wea":"晴","wea_img":"qing","tem1":"36℃","tem2":"28℃","tem":"30℃","win":["南风","南风"],"win_speed":"<3级","hours":[{"day":"18日08时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"18日14时","wea":"晴","tem":"36℃","win":"南风","win_speed":"<3级"},{"day":"18日20时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"19日02时","wea":"晴","tem":"28℃","win":"南风","win_speed":"<3级"}],"index":[{"title":"中国人民保险
中暑指数","level":"较易中暑","desc":"酷热难耐,外出尽量不要打赤膊,通风的棉衫和赤膊相比更有消暑的作用。"},{"title":"<\/em><\/em><\/em>","level":null,"desc":"天气有点热,运动多补水。"},{"title":"健臻·血糖指数","level":"易波动","desc":"气温高,血糖易波动,注意防暑降温。"},{"title":"穿衣指数","level":"炎热","desc":"建议穿短衫、短裤等清凉夏季服装。"},{"title":"洗车指数","level":"适宜","desc":"天气较好,适合擦洗汽车。"},{"title":"紫外线指数","level":"很强","desc":"涂擦SPF20以上,PA++护肤品,避强光。"}]},{"day":"19日(周三)","date":"2020-08-19","week":"星期三","wea":"晴","wea_img":"qing","tem1":"36℃","tem2":"28℃","tem":"30℃","win":["南风","南风"],"win_speed":"<3级","hours":[{"day":"19日08时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"19日14时","wea":"晴","tem":"35℃","win":"南风","win_speed":"<3级"},{"day":"19日20时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"20日02时","wea":"晴","tem":"28℃","win":"南风","win_speed":"<3级"}],"index":[{"title":"中国人民保险
中暑指数","level":"易中暑","desc":"又是蒸桑拿的一天,记得多喝盐开水,随身携带防暑药物。"},{"title":"<\/em><\/em><\/em>","level":null,"desc":"天气有点热,运动多补水。"},{"title":"健臻·血糖指数","level":"易波动","desc":"气温高,血糖易波动,注意防暑降温。"},{"title":"穿衣指数","level":"炎热","desc":"建议穿短衫、短裤等清凉夏季服装。"},{"title":"洗车指数","level":"适宜","desc":"天气较好,适合擦洗汽车。"},{"title":"紫外线指数","level":"很强","desc":"涂擦SPF20以上,PA++护肤品,避强光。"}]},{"day":"20日(周四)","date":"2020-08-20","week":"星期四","wea":"晴","wea_img":"qing","tem1":"37℃","tem2":"29℃","tem":"30℃","win":["南风","南风"],"win_speed":"<3级","hours":[{"day":"20日08时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"20日14时","wea":"晴","tem":"37℃","win":"南风","win_speed":"<3级"},{"day":"20日20时","wea":"晴","tem":"32℃","win":"南风","win_speed":"<3级"},{"day":"21日02时","wea":"晴","tem":"29℃","win":"南风","win_speed":"<3级"}],"index":[{"title":"中国人民保险
中暑指数","level":"易中暑","desc":"夏日炎炎,到户外要配搭帽子和遮阳伞。"},{"title":"<\/em><\/em><\/em>","level":null,"desc":"天气有点热,运动多补水。"},{"title":"健臻·血糖指数","level":"易波动","desc":"气温高,血糖易波动,注意防暑降温。"},{"title":"穿衣指数","level":"炎热","desc":"建议穿短衫、短裤等清凉夏季服装。"},{"title":"洗车指数","level":"适宜","desc":"天气较好,适合擦洗汽车。"},{"title":"紫外线指数","level":"很强","desc":"涂擦SPF20以上,PA++护肤品,避强光。"}]},{"day":"21日(周五)","date":"2020-08-21","week":"星期五","wea":"晴","wea_img":"qing","tem1":"37℃","tem2":"29℃","tem":"31℃","win":["南风","南风"],"win_speed":"<3级","hours":[{"day":"21日08时","wea":"晴","tem":"31℃","win":"南风","win_speed":"<3级"},{"day":"21日14时","wea":"晴","tem":"36℃","win":"南风","win_speed":"<3级"},{"day":"21日20时","wea":"晴","tem":"32℃","win":"南风","win_speed":"<3级"},{"day":"22日02时","wea":"晴","tem":"29℃","win":"南风","win_speed":"<3级"}],"index":[{"title":"中国人民保险
中暑指数","level":"较易中暑","desc":"夏日炎炎,到户外要配搭帽子和遮阳伞。"},{"title":"<\/em><\/em><\/em>","level":null,"desc":"天气有点热,运动多补水。"},{"title":"健臻·血糖指数","level":"易波动","desc":"气温高,血糖易波动,注意防暑降温。"},{"title":"穿衣指数","level":"炎热","desc":"建议穿短衫、短裤等清凉夏季服装。"},{"title":"洗车指数","level":"适宜","desc":"天气较好,适合擦洗汽车。"},{"title":"紫外线指数","level":"很强","desc":"涂擦SPF20以上,PA++护肤品,避强光。"}]}] */
private String cityid; private String update_time; private String city; private String cityEn; private String country; private String countryEn; private List<DataBean> data; public String getCityid() { return cityid; } public void setCityid(String cityid) { this.cityid = cityid; } public String getUpdate_time() { return update_time; } public void setUpdate_time(String update_time) { this.update_time = update_time; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getCityEn() { return cityEn; } public void setCityEn(String cityEn) { this.cityEn = cityEn; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getCountryEn() { return countryEn; } public void setCountryEn(String countryEn) { this.countryEn = countryEn; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { /** * day : 15日(今天) * date : 2020-08-15 * week : 星期六 * wea : 晴 * wea_img : qing * air : 22 * humidity : 76 * air_level : 优 * air_tips : 空气很好,可以外出活动,呼吸新鲜空气,拥抱大自然! * alarm : {"alarm_type":"","alarm_level":"","alarm_content":""} * tem1 : 36℃ * tem2 : 27℃ * tem : 29℃ * win : ["南风","南风"] * win_speed : 3-4级转<3级 * hours : [{"day":"15日08时","wea":"多云","tem":"29℃","win":"南风","win_speed":"3-4级"},{"day":"15日11时","wea":"晴","tem":"32℃","win":"南风","win_speed":"3-4级"},{"day":"15日14时","wea":"晴","tem":"34℃","win":"南风","win_speed":"3-4级"},{"day":"15日17时","wea":"晴","tem":"35℃","win":"南风","win_speed":"<3级"},{"day":"15日20时","wea":"晴","tem":"30℃","win":"南风","win_speed":"<3级"},{"day":"15日23时","wea":"晴","tem":"29℃","win":"南风","win_speed":"<3级"},{"day":"16日02时","wea":"晴","tem":"28℃","win":"南风","win_speed":"<3级"},{"day":"16日05时","wea":"晴","tem":"27℃","win":"南风","win_speed":"<3级"}] * index : [{"title":"中国人民保险
中暑指数","level":"较易中暑","desc":"长时间户外工作的你要适当调整作业时间,备好遮阳设施,及时补充盐分。"},{"title":"<\/em><\/em><\/em>","level":null,"desc":"天热风大,可选择低强度运动。"},{"title":"健臻·血糖指数","level":"易波动","desc":"气温高,血糖易波动,注意防暑降温。"},{"title":"穿衣指数","level":"炎热","desc":"建议穿短衫、短裤等清凉夏季服装。"},{"title":"洗车指数","level":"较不宜","desc":"风力较大,洗车后会蒙上灰尘。"},{"title":"紫外线指数","level":"很强","desc":"涂擦SPF20以上,PA++护肤品,避强光。"}] */
private String day; private String date; private String week; private String wea; private String wea_img; private int air; private int humidity; private String air_level; private String air_tips; private AlarmBean alarm; private String tem1; private String tem2; private String tem; private String win_speed; private List<String> win; private List<HoursBean> hours; private List<IndexBean> index; public String getDay() { return day; } public void setDay(String day) { this.day = day; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getWeek() { return week; } public void setWeek(String week) { this.week = week; } public String getWea() { return wea; } public void setWea(String wea) { this.wea = wea; } public String getWea_img() { return wea_img; } public void setWea_img(String wea_img) { this.wea_img = wea_img; } public int getAir() { return air; } public void setAir(int air) { this.air = air; } public int getHumidity() { return humidity; } public void setHumidity(int humidity) { this.humidity = humidity; } public String getAir_level() { return air_level; } public void setAir_level(String air_level) { this.air_level = air_level; } public String getAir_tips() { return air_tips; } public void setAir_tips(String air_tips) { this.air_tips = air_tips; } public AlarmBean getAlarm() { return alarm; } public void setAlarm(AlarmBean alarm) { this.alarm = alarm; } public String getTem1() { return tem1; } public void setTem1(String tem1) { this.tem1 = tem1; } public String getTem2() { return tem2; } public void setTem2(String tem2) { this.tem2 = tem2; } public String getTem() { return tem; } public void setTem(String tem) { this.tem = tem; } public String getWin_speed() { return win_speed; } public void setWin_speed(String win_speed) { this.win_speed = win_speed; } public List<String> getWin() { return win; } public void setWin(List<String> win) { this.win = win; } public List<HoursBean> getHours() { return hours; } public void setHours(List<HoursBean> hours) { this.hours = hours; } public List<IndexBean> getIndex() { return index; } public void setIndex(List<IndexBean> index) { this.index = index; } public static class AlarmBean { /** * alarm_type : * alarm_level : * alarm_content : */ private String alarm_type; private String alarm_level; private String alarm_content; public String getAlarm_type() { return alarm_type; } public void setAlarm_type(String alarm_type) { this.alarm_type = alarm_type; } public String getAlarm_level() { return alarm_level; } public void setAlarm_level(String alarm_level) { this.alarm_level = alarm_level; } public String getAlarm_content() { return alarm_content; } public void setAlarm_content(String alarm_content) { this.alarm_content = alarm_content; } } public static class HoursBean { /** * day : 15日08时 * wea : 多云 * tem : 29℃ * win : 南风 * win_speed : 3-4级 */ private String day; private String wea; private String tem; private String win; private String win_speed; public String getDay() { return day; } public void setDay(String day) { this.day = day; } public String getWea() { return wea; } public void setWea(String wea) { this.wea = wea; } public String getTem() { return tem; } public void setTem(String tem) { this.tem = tem; } public String getWin() { return win; } public void setWin(String win) { this.win = win; } public String getWin_speed() { return win_speed; } public void setWin_speed(String win_speed) { this.win_speed = win_speed; } } public static class IndexBean { /** * title : 中国人民保险
中暑指数 * level : 较易中暑 * desc : 长时间户外工作的你要适当调整作业时间,备好遮阳设施,及时补充盐分。 */
private String title; private String level; private String desc; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getLevel() { return level; } public void setLevel(String level) { this.level = level; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } } } }

第四步:

activity_weather.xml


<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:orientation="vertical"
    tools:context=".WeatherActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary">

        <TextView
            android:id="@+id/title_city"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textSize="20sp"
            android:textColor="#fff"
            tools:text="济南"/>

        <TextView
            android:id="@+id/title_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:textSize="16sp"
            android:textColor="#fff"
            android:layout_marginRight="12dp"
            android:layout_marginEnd="12dp"
            tools:text="15:00" />

    RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="32dp">

        <TextView
            android:id="@+id/degree"
            android:textColor="#000"
            android:textSize="60sp"
            tools:text="20℃"
            android:layout_gravity="end"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/weather_info"
            android:textColor="#000"
            android:textSize="20sp"
            tools:text=""
            android:layout_gravity="end"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    LinearLayout>

    <LinearLayout
        android:padding="32dp"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#8000">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="预报"
            android:textColor="#fff"
            android:textSize="20sp"/>

        <LinearLayout
            android:id="@+id/forecast_layout"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        LinearLayout>

    LinearLayout>

LinearLayout>

效果图:

Android开发实战-项目学习笔记(2)_第40张图片

forecast_item.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="16dp">

    <TextView
        android:id="@+id/date"
        android:textSize="16sp"
        android:text="2020-8-12"
        android:textColor="#fff"
        android:gravity="center"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

    <TextView
        android:id="@+id/wea_info"
        android:textSize="16sp"
        android:text=""
        android:textColor="#fff"
        android:gravity="center"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    
    <TextView
        android:id="@+id/h_degree"
        android:textSize="16sp"
        android:text="30"
        android:textColor="#fff"
        android:gravity="center"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

    <TextView
        android:id="@+id/l_degree"
        android:textSize="16sp"
        android:text="27"
        android:textColor="#fff"
        android:gravity="center"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

LinearLayout>

layout_weight=“1” 设置权重

第五步:

package com.example.jnsyq;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.jnsyq.data.Forecast;
import com.example.jnsyq.data.InTimeWeather;
import com.example.jnsyq.utils.HttpUtils;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class WeatherActivity extends AppCompatActivity {

    private InTimeWeather inTimeWeather;
    private Forecast forecast;

    //声明控件
    private TextView titleCity;
    private TextView titleTime;
    private TextView degree;
    private TextView weatherInfo;
    private LinearLayout foreLayout;

    private String cityid; //private protected public(默认:protected)

    Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case 0:
                    //调用更新ui方法
                    updateUi();
                    break;
                case 1:
                    //调用7天预报更新方法
                    updateForecast();
                    break;
                default:
                    break;
            }
        }
    };

    public static void actionStart(Context context, String cityid) {
        Intent intent = new Intent(context, WeatherActivity.class);
        intent.putExtra("cityid", cityid);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_weather);

        //从布局中找到控件
        titleCity = findViewById(R.id.title_city);
        titleTime = findViewById(R.id.title_time);
        degree = findViewById(R.id.degree);
        weatherInfo = findViewById(R.id.weather_info);
        foreLayout = findViewById(R.id.forecast_layout);

        //获取意图
        Intent intent = getIntent();
        //获取上一个活动传递劲来的数据
        //初始化cityid的值
        cityid = intent.getStringExtra("cityid");

        //调用该方法获取数据
        getWeatherInfo();
        getForecaseInfo();
    }

    private void updateUi() {
        //设置对应值
        titleCity.setText(inTimeWeather.getCity());
        titleTime.setText(inTimeWeather.getUpdate_time().split(" ")[1]);
        degree.setText(inTimeWeather.getTem() + "℃");
        weatherInfo.setText(inTimeWeather.getWea());
    }

    private void updateForecast() {
        //遍历7天数据
        //forecast.getData().for 自动出
        for (Forecast.DataBean dataBean : forecast.getData()) {
            //通过布局文件创建view
            View view = LayoutInflater.from(this).inflate(R.layout.forecast_item, foreLayout, false);
            //获取布局文件的控件
            TextView date = view.findViewById(R.id.date);
            TextView wea = view.findViewById(R.id.wea_info);
            TextView hDegree = view.findViewById(R.id.h_degree);
            TextView lDegree = view.findViewById(R.id.l_degree);
            //设置值
            date.setText(dataBean.getWeek());
            wea.setText(dataBean.getWea());
            hDegree.setText(dataBean.getTem1());
            lDegree.setText(dataBean.getTem2());
            //添加布局view
            foreLayout.addView(view);
        }
    }

    /**
     * 创建获取实时天气的方法
     */
    private void getWeatherInfo() {
        //通过调用api获取天气信息
        //直接通过ip地址进行天气信息获取
        //cityid:变量,由上一个活动传递进来
        String url = "http://www.tianqiapi.com/api?version=v6&appid=72458447&appsecret=E2P8xV9n&cityid=" + cityid.replace("CN", "");
        //获取网络信息
        //网络访问需要新开线程进行执行,不影响主线程
        HttpUtils.sendOkhttpRequest(url, new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //读取返回的数据
                String data = response.body().string();
                //新建gson对象
                Gson gson = new Gson();
                //解析json数据,初始化inTimeWeather
                inTimeWeather = gson.fromJson(data, InTimeWeather.class); //json格式化

                //初始化天气以后,发送消息,更新ui界面
                Message msg = new Message();
                msg.what = 0;
                handler.sendMessage(msg);
            }
        });
    }

    /**
     * 创建获取七日天气数据的方法
     */
    private void getForecaseInfo() {
         String url = "http://www.tianqiapi.com/api?version=v1&appid=72458447&appsecret=E2P8xV9n&cityid="
                + cityid.replace("CN", "");
         HttpUtils.sendOkhttpRequest(url, new Callback() {
             @Override
             public void onFailure(@NotNull Call call, @NotNull IOException e) {
                 e.printStackTrace();
             }

             @Override
             public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                String data = response.body().string();
                Gson gson = new Gson();
                forecast = gson.fromJson(data, Forecast.class);

                 Message msg = new Message();
                 msg.what = 1;
                 handler.sendMessage(msg);
             }
         });
    }

}

效果图:

Android开发实战-项目学习笔记(2)_第41张图片

你可能感兴趣的:(Android,android,studio,android)