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();
                }
            }
        });
    }

}

效果图:

在这里插入图片描述

获取省级信息

代码部分:

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();
                }
            }
        });
    }

}

效果图:

在这里插入图片描述

省市县返回问题

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

第一步:

res/values中,修改styles.xml代码,效果如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第二步:

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

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

ic_home.png

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android: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:占位,程序运行时不会显示出来

效果图:

在这里插入图片描述

第三步:

声明控件

标题自定义

主要代码,截图:
在这里插入图片描述

Button返回

主要代码,截图:
在这里插入图片描述

问题:

网络访问

省级 -> 市级 -> 网络访问 需要
市级 -> 省级 -> 网络访问 不需要
修改代码,截图:
在这里插入图片描述
在这里插入图片描述
注:清空

反复重写

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工具类,截图和代码部分如下:

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表示对未完成情况做标记
在这里插入图片描述

效果图:

省级:

在这里插入图片描述

市级:

在这里插入图片描述

县级:

在这里插入图片描述

控制台

在这里插入图片描述

显示地名和时间

第一步:

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

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

在这里插入图片描述

  • 选择GsonFormat

在这里插入图片描述效果图如下:
在这里插入图片描述

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

在这里插入图片描述
效果图如下:
在这里插入图片描述

  • 效果如图,点击OK

在这里插入图片描述

代码部分:

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,修改名称,效果如下:
在这里插入图片描述
在这里插入图片描述
MainActivity.java中添加代码,如下:
在这里插入图片描述

第三步:

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

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

注意:点击Sync Now
在WeatherActivity.java中,使用gson获取数据,代码如下:
在这里插入图片描述

第四步:

activity_weather.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android: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的倍数

效果图:

在这里插入图片描述

第四步:

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

法1:

MainActivity.java
在这里插入图片描述
WeatherActivity.java
在这里插入图片描述

法2:

注意:该方法的作用为避免传输数据类型排错
MainActivity.java
在这里插入图片描述
WeatherActivity.java
在这里插入图片描述

问题:

NullPointerException

变量被声明,没有初始化,内存中不存在被调用导致空指针异常
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码部分:

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);
            }
        });
    }

}

效果图:

在县级下选择桦南,效果如下:
在这里插入图片描述

城市id存储

  • sharedpreferences
  • sqlite(数据库)

cityid:101120901

注意:使用sharedpreferences,使得每次打开app的时候查看上次是否选择城市,如果选择了,无需再选
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);

        //创建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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android: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>

效果图:

在这里插入图片描述

第二步:

WeatherActivity.java
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

效果图:

在这里插入图片描述

第三步:

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":"中国人民保险<br>中暑指数","level":"较易中暑","desc":"长时间户外工作的你要适当调整作业时间,备好遮阳设施,及时补充盐分。"},{"title":"<\/em><em><\/em><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":"中国人民保险<br>中暑指数","level":"较易中暑","desc":"炎炎夏日里,出行尽量穿浅色或素色服装。"},{"title":"<\/em><em><\/em><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":"中国人民保险<br>中暑指数","level":"易中暑","desc":"酷暑炎炎,尽量避免在上午10点至下午2点外出。"},{"title":"<\/em><em><\/em><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":"中国人民保险<br>中暑指数","level":"较易中暑","desc":"酷热难耐,外出尽量不要打赤膊,通风的棉衫和赤膊相比更有消暑的作用。"},{"title":"<\/em><em><\/em><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":"中国人民保险<br>中暑指数","level":"易中暑","desc":"又是蒸桑拿的一天,记得多喝盐开水,随身携带防暑药物。"},{"title":"<\/em><em><\/em><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":"中国人民保险<br>中暑指数","level":"易中暑","desc":"夏日炎炎,到户外要配搭帽子和遮阳伞。"},{"title":"<\/em><em><\/em><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":"中国人民保险<br>中暑指数","level":"较易中暑","desc":"夏日炎炎,到户外要配搭帽子和遮阳伞。"},{"title":"<\/em><em><\/em><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":"中国人民保险<br>中暑指数","level":"较易中暑","desc":"长时间户外工作的你要适当调整作业时间,备好遮阳设施,及时补充盐分。"},{"title":"<\/em><em><\/em><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 : 中国人民保险<br>中暑指数
             * 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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android: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>
效果图:

在这里插入图片描述

forecast_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_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);
             }
         });
    }

}

效果图:

在这里插入图片描述

1、Android团队提供的示例项目   如果不是从学习Android SDK中提供的那些样例代码开始,可能没有更好的方法来掌握在Android这个框架上开发。由Android的核心开发团队提供了15个优秀的示例项目,包含了游戏、图像处理、时间显示、开始菜单快捷方式等。   2、 Remote Droid   RemoteDroid是一个Android应用,能够让用户使用自己的无线网络使用无线键盘、触摸屏操作手机。这个项目开发者提供了如网络连接、触摸屏手指运动等很好的样例。   3、 TorProxy和Shadow   TorProxy应用实现了Android手机无线电电传通讯(TOR),和Shadow应用一起使用,可以使用手机匿名上网。从该项目源代码中,可以掌握socket连接、管理cookie等方法。      4、 Android SMSPopup   SMSPopup可以截获短信内容显示在一个泡泡形状的窗口中。从这个项目中可以掌握到如何使用内置的短信SMS接口。   5、 Standup Timer   Standup Timer应用用于控制站立会议时间,类似秒表倒计时,可以提醒每个人的讲话时间已到,从而保证每个与会者使用时间一样。从该项目的代码中,可以学会如何使用时间函数。另外,这个项目的代码是采用视图view、模型model严格分离的设计思路。      6、 Foursquare   是Foursquare.com的一个客户端应用,该应用主要分为两个模块:API(com.joelapenna.foursquare)和界面前端 (com.joelapenna.foursquared)两部分。从该项目代码中,可以学会如何同步、多线程、HTTP连接等技术。   7、 Pedometer   Pedometer应用用于记录你每天走路步数的。尽管记录不一定精准,但是从这个项目中,可以学习几个不同的技术:加速器交互、语音更新、后台运行服务等。   8、 OpenSudoku-android   OpenSudoku是一个简单的九宫格数独游戏。从代码中可以学习到如何在视图中显示表格数据,以及如何和一个网站交互等技术。   9、 ConnectBot   ConnectBot是Android平台的一个客户端安全壳应用。从该项目代码中,可以学习到很多Android安全方面的内容,这些是你在开发应用时经常需要考虑的安全问题。   10、 WordPress的Android应用   当然在最后不能不提WordPress的Android应用了,这是WordPress官方开发团队提供的一个项目。从代码中可以学习到XMLRPC调用(当然还有更多的优秀内容)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值