Android简单版天气预报,显示天气预报(第二步)

接着上一步的:[https://blog.csdn.net/weixin_44889138/article/details/102748057]
上一步的链接

ListView的改进,因为每次在getView()方法中还是会调用View的findViewById()方法来获取一次控件的实例,写一个内部类,利用**view.setTag()**存储,getTag()取。其实实现的机制跟RecycleView差不多

package com.example.xhhweather;import android.content.Intent;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import java.util.List;public class CityAdapter extends BaseAdapter {    //    class ViewHolder{        TextView TVcityName;        //删除城市        ImageView ivDelCity;        //选择城市后返回天气界面        ImageView ivQuyCity;    }    private List<CityItem> list;    public CityAdapter(List<CityItem> list){        this.list=list;    }    @Override    public View getView(final int position, View covertView, final ViewGroup viewGroup) {        View view;        ViewHolder viewHolder;        if(covertView==null){            view= LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.city_item,viewGroup,false);            viewHolder=new ViewHolder();            viewHolder.TVcityName=view.findViewById(R.id.tv_city_name);            viewHolder.ivQuyCity=view.findViewById(R.id.btn_move);            viewHolder.ivDelCity=view.findViewById(R.id.iv_del_city);            //将viewHolder存入在view中            view.setTag(viewHolder);        }else{            view=covertView;            viewHolder= (ViewHolder) view.getTag();        }        CityItem cityItem= list.get(position);        viewHolder.TVcityName.setText(cityItem.getCityName());        //删除城市        viewHolder.ivDelCity.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                list.remove(position);                notifyDataSetChanged();//本身就是adapter            }        });        //移动城市        viewHolder.ivQuyCity.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                CityItem city=list.get(position);                Toast.makeText(viewGroup.getContext(),city.getCityPinYin(),Toast.LENGTH_SHORT).show();            }        });        return view;    }    @Override    public int getCount() {        return list.size();    }    @Override    public Object getItem(int i) {        return list.get(i);    }    @Override    public long getItemId(int i) {        return i;    }}
package com.example.xhhweather;import androidx.annotation.Nullable;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.bumptech.glide.Glide;import com.example.xhhweather.gson.Weather;import com.example.xhhweather.gson.WeatherResDaily;import com.example.xhhweather.gson.WeatherResults;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;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{    private Button btnSelectCity;    private TextView weatherTitleCityname;    private TextView tvFirstDayDate;    private TextView tvFirstDayPhe;    private TextView tvFirstDayHigh;    private TextView tvFirstDayLow;    private TextView tvSecondDayDate;    private TextView tvSecondDayPhe;    private TextView tvSecondDayHigh;    private TextView tvSecondDayLow;    private TextView tvThirdDayDate;    private TextView tvThirdDayPhe;    private TextView tvThirdDayHigh;    private TextView tvThirdDayLow;    private TextView temperatureText;    private TextView caseText;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initfindViewById();        btnSelectCity.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Intent intent=new Intent(MainActivity.this,SelectCity.class);                startActivityForResult(intent,1001);            }        });    }    /**     * 初始化     */    private void initfindViewById(){        btnSelectCity=findViewById(R.id.manage_city_btn);        weatherTitleCityname=findViewById(R.id.weather_title_cityname);        temperatureText=findViewById(R.id.temperature_text);        caseText=findViewById(R.id.case_text);        tvFirstDayDate=findViewById(R.id.tv_firstday_date);        tvFirstDayPhe=findViewById(R.id.tv_firstday_phe);        tvFirstDayHigh=findViewById(R.id.tv_firstday_high);        tvFirstDayLow=findViewById(R.id.tv_firstday_low);        tvSecondDayDate=findViewById(R.id.tv_secondday_date);        tvSecondDayPhe=findViewById(R.id.tv_secondday_phe);        tvSecondDayHigh=findViewById(R.id.tv_secondday_high);        tvSecondDayLow=findViewById(R.id.tv_secondday_low);        tvThirdDayDate=findViewById(R.id.tv_thirdday_date);        tvThirdDayPhe=findViewById(R.id.tv_thirdday_phe);        tvThirdDayHigh=findViewById(R.id.tv_thirdday_high);        tvThirdDayLow=findViewById(R.id.tv_thirdday_low);    }    /**     * 得到     * @param requestCode     * @param resultCode     * @param data     */    @Override    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if(requestCode==1001 && resultCode==1002){            String cityPinYin=data.getStringExtra("CITYPINYIN");            //Log.e("MainActivity","返回城市的拼音"+cityPinYin);            //心知天气的api            String url="https://api.seniverse.com/v3/weather/daily.json?key=SojsF4VNkV_cTQexq&location=" + cityPinYin + "&language=zh-Hans&unit=c&start=0&days=5";            HttpUtil.sendOkHttpRequest(url, new Callback() {                @Override                public void onFailure(Call call, IOException e) {                    e.printStackTrace();                }                @Override                public void onResponse(Call call, Response response) throws IOException {                    final String weatherData=response.body().string();                    runOnUiThread(new Runnable() {                        @Override                        public void run() {                            Log.e("MainActivity","得到的数据"+weatherData);                            Gson gson =new Gson();                            Weather weatherInfo=gson.fromJson(weatherData,Weather.class);                            WeatherResults results=weatherInfo.getResults().get(0);                            String cityName=results.getLocation().getName();//城市名称                            weatherTitleCityname.setText(cityName);                            //将3天内的天气数据获得后存入二维数组                            String [] [] resultDaily=new String[3][5];                            for(int i=0;i<3;i++){                                for(int j=0;j<4;){                                    resultDaily[i][j]=results.getDaily().get(i).getDate();j++;                                    resultDaily[i][j]=results.getDaily().get(i).getText_day();j++;                                    resultDaily[i][j]=results.getDaily().get(i).getHigh();j++;                                    resultDaily[i][j]=results.getDaily().get(i).getLow();j++;                                }                            }                            temperatureText.setText(resultDaily[0][2]+"℃");                            caseText.setText(resultDaily[0][1]);                            for(int j=0;j<4;){                                //Log.e("resultDaily",resultDaily[0][j]);                                tvFirstDayDate.setText(resultDaily[0][j]);j++;                                tvFirstDayPhe.setText(resultDaily[0][j]);j++;                                tvFirstDayHigh.setText(resultDaily[0][j]);j++;                                tvFirstDayLow.setText(resultDaily[0][j]);j++;                            }                            for(int j=0;j<4;){                                tvSecondDayDate.setText(resultDaily[1][j]);j++;                                tvSecondDayPhe.setText(resultDaily[1][j]);j++;                                tvSecondDayHigh.setText(resultDaily[1][j]);j++;                                tvSecondDayLow.setText(resultDaily[1][j]);j++;                            }                            for(int j=0;j<4;){                                tvThirdDayDate.setText(resultDaily[2][j]);j++;                                tvThirdDayPhe.setText(resultDaily[2][j]);j++;                                tvThirdDayHigh.setText(resultDaily[2][j]);j++;                                tvThirdDayLow.setText(resultDaily[2][j]);j++;                            }                        }                    });                }            });        }    }}
package com.example.xhhweather;import okhttp3.OkHttpClient;import okhttp3.Request;public class HttpUtil {    public static void sendOkHttpRequest(String url,okhttp3.Callback callback){        OkHttpClient client=new OkHttpClient();        Request request=new Request.Builder()                .url(url)                .build();        client.newCall(request).enqueue(callback);    }}

接下来,分析重点
首先看一下心知天气文档,得知需要城市拼音,才能利用api得到不同城市的接口,返回的数据是json格式

访问api需要使用HTTP协议访问网络,那么应该得先想到要用到网络的权限
uses-permission android:name=“android.permission.INTERNET”

这里我用的是OkHttp代替HttpURLConnecion,需要导入依赖
implementation ‘com.squareup.okhttp3:okhttp:3.4.1’

如果不熟悉用法,那就从简单的做起,我介绍怎么简单获得必应图片的每日一图,与本项目有间接的关系(后期用到)

导入这个依赖 implementation ‘com.github.bumptech.glide:glide:4.10.0’,简单快捷可以将图片加载,而且容易理解

建一个HttpUtil类的原因
一个应用程序很可能会在许多地方都使用到网络功能,而发送HTTP请求的代码基本相同,如果每次都去编写,这显然很差劲,将这些通用的网络操作提取到一个公共的类里,并提供一个静态方法

package com.example.atuogetpic;import okhttp3.OkHttpClient;import okhttp3.Request;public class HttpUtil {    public static void sendOkHttpRequest(String address,okhttp3.Callback callback){        OkHttpClient client=new OkHttpClient();        Request request=new Request.Builder()                .url(address)                .build();        client.newCall(request).enqueue(callback);    }}
package com.example.atuogetpic;import androidx.appcompat.app.AppCompatActivity;import android.content.SharedPreferences;import android.os.Bundle;import android.preference.PreferenceManager;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageView;import com.bumptech.glide.Glide;import java.io.IOException;import okhttp3.Call;import okhttp3.Callback;import okhttp3.HttpUrl;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;import static android.preference.PreferenceManager.getDefaultSharedPreferences;public class MainActivity extends AppCompatActivity {    private ImageView bingPicImg;    private Button btnQ;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        bingPicImg=findViewById(R.id.bing_pic_img);        btnQ=findViewById(R.id.btn);        btnQ.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                loadBingPic();            }        });    }    /**     * 加载必应每日一图     */    private void loadBingPic(){        final String requestBingPic="http://guolin.tech/api/bing_pic";        HttpUtil.sendOkHttpRequest(requestBingPic, new Callback() {            @Override            public void onResponse(Call call, Response response) throws IOException {                final String bingPic=response.body().string();                SharedPreferences.Editor editor=                        getSharedPreferences("bing_pic",MODE_PRIVATE).edit();                editor.putString("bing_pic",bingPic);                editor.apply();                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        Glide.with(MainActivity.this).load(bingPic).into(bingPicImg);//加载图片                    }                });            }            @Override            public void onFailure(Call call, IOException e) {                e.printStackTrace();            }        });    }}
<?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"    tools:context=".MainActivity"    android:orientation="vertical">    <Button        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:id="@+id/btn"        android:text="换图"/>    <ImageView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:id="@+id/bing_pic_img"        android:src="@drawable/bg"/></LinearLayout>

好了,网络请求应该都会了吧

接下来才是重头戏,需要解析json里的数据,但是返回的数据太过复杂(可以看心知天气文档)
可以用gson解析 ,需要导入依赖
implementation ‘com.google.code.gson:gson:2.8.5’

它主要可以将一段json格式的字符串自动映射成一个对象,不用我们去编写代码解析
{
“results”:[
{
“location”:{“id”:“WTW3SJ5ZBJUY”,“name”:“上海”,“country”:“CN”,“path”:“上海,上海,中国”,“timezone”:“Asia/Shanghai”,“timezone_offset”:"+08:00"}
,“daily”:[
{ “date”:“2019-10-28”,“text_day”:“多云”,“code_day”:“4”,“text_night”:“晴”,“code_night”:“1”,“high”:“21”,“low”:“14”,“precip”:"",“wind_direction”:“西”,“wind_direction_degree”:“270”,“wind_speed”:“16.20”,“wind_scale”:“3”}
,{“date”:“2019-10-29”,“text_day”:“晴”,“code_day”:“0”,“text_night”:“晴”,“code_night”:“1”,“high”:“22”,“low”:“14”,“precip”:"",“wind_direction”:“东北”,“wind_direction_degree”:“45”,“wind_speed”:“25.20”,“wind_scale”:“4”}
,{“date”:“2019-10-30”,“text_day”:“晴”,“code_day”:“0”,“text_night”:“晴”,“code_night”:“1”,“high”:“22”,“low”:“14”,“precip”:"",“wind_direction”:“东”,“wind_direction_degree”:“90”,“wind_speed”:“16.20”,“wind_scale”:“3”}
],
“last_update”:“2019-10-28T11:17:53+08:00”
}
]
}

解析这个json数据
1.{ }里面是一个一个results数组,就应该写成列表,而weather类表示 { }

package com.example.xhhweather.gson;import java.util.List;public class Weather {    private List<WeatherResults> results;//命名一定要与数据中的相同,一定要对应    public List<WeatherResults> getResults() {        return results;    }    public void setResults(List<WeatherResults> results) {        this.results = results;    }    @Override    public String toString() {        return "Weather{" +                "results=" + results +                '}';    }} 

2.建一个WeatherResults类,results数组里面又有"location":{},“daily”:[],“last_update”:一个字符串

package com.example.xhhweather.gson;import java.util.List; public class WeatherResults {     private WeatherResLocation location;//对应location:{},命名一定要与数据中的相同,一定要对应     private List<WeatherResDaily> daily;//对应daily:数组     private String last_update;//对应"last_update":一个字符串     public WeatherResLocation getLocation() {         return location;     }     public List<WeatherResDaily> getDaily() {         return daily;     }     public String getLast_update() {         return last_update;     }     public void setLocation(WeatherResLocation location) {         this.location = location;     }     public void setDaily(List<WeatherResDaily> daily) {         this.daily = daily;     }     public void setLast_update(String last_update) {         this.last_update = last_update;     }     @Override     public String toString() {         return "WeatherResults{" +                 "location=" + location +                 ", daily=" + daily +                 ", last_update='" + last_update + '\'' +                 '}';     } }
package com.example.xhhweather.gson;public class WeatherResDaily {    private String date;    private String text_day;    private String code_day;    private String text_night;    private String code_night;    private String high;    private String low;    private String precip;    private String wind_direction;    private String wind_direction_degree;    private String wind_speed;    private String wind_scale;    public String getDate() {        return date;    }    public String getText_day() {        return text_day;    }    public String getCode_day() {        return code_day;    }    public String getText_night() {        return text_night;    }    public String getCode_night() {        return code_night;    }    public String getHigh() {        return high;    }    public String getLow() {        return low;    }    public String getPrecip() {        return precip;    }    public String getWind_direction() {        return wind_direction;    }    public String getWind_direction_degree() {        return wind_direction_degree;    }    public String getWind_speed() {        return wind_speed;    }    public String getWind_scale() {        return wind_scale;    }    public void setDate(String date) {        this.date = date;    }    public void setText_day(String text_day) {        this.text_day = text_day;    }    public void setCode_day(String code_day) {        this.code_day = code_day;    }    public void setText_night(String text_night) {        this.text_night = text_night;    }    public void setCode_night(String code_night) {        this.code_night = code_night;    }    public void setHigh(String high) {        this.high = high;    }    public void setLow(String low) {        this.low = low;    }    public void setPrecip(String precip) {        this.precip = precip;    }    public void setWind_direction(String wind_direction) {        this.wind_direction = wind_direction;    }    public void setWind_direction_degree(String wind_direction_degree) {        this.wind_direction_degree = wind_direction_degree;    }    public void setWind_speed(String wind_speed) {        this.wind_speed = wind_speed;    }    public void setWind_scale(String wind_scale) {        this.wind_scale = wind_scale;    }    @Override    public String toString() {        return "WeatherResDaily{" +                "date='" + date + '\'' +                ", text_day='" + text_day + '\'' +                ", code_day='" + code_day + '\'' +                ", text_night='" + text_night + '\'' +                ", code_night='" + code_night + '\'' +                ", high='" + high + '\'' +                ", low='" + low + '\'' +                ", precip='" + precip + '\'' +                ", wind_direction='" + wind_direction + '\'' +                ", wind_direction_degree='" + wind_direction_degree + '\'' +                ", wind_speed='" + wind_speed + '\'' +                ", wind_scale='" + wind_scale + '\'' +                '}';    }}
package com.example.xhhweather.gson;public class WeatherResLocation {    private String id;    private String name;    private String country;    private String path;    private String timezone;    private String timezone_offset;    public String getId() {        return id;    }    public String getName() {        return name;    }    public String getCountry() {        return country;    }    public String getPath() {        return path;    }    public String getTimezone() {        return timezone;    }    public String getTimezone_offset() {        return timezone_offset;    }    public void setId(String id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    public void setCountry(String country) {        this.country = country;    }    public void setPath(String path) {        this.path = path;    }    public void setTimezone(String timezone) {        this.timezone = timezone;    }    public void setTimezone_offset(String timezone_offset) {        this.timezone_offset = timezone_offset;    }    @Override    public String toString() {        return "WeatherResLocation{" +                "id='" + id + '\'' +                ", name='" + name + '\'' +                ", country='" + country + '\'' +                ", path='" + path + '\'' +                ", timezone='" + timezone + '\'' +                ", timezone_offset='" + timezone_offset + '\'' +                '}';    }}

代码可以自动生成,右键点击general(首先要先命名)

Gson gson =new Gson();
Weather weatherInfo=gson.fromJson(weatherData,Weather.class);
weatherData为你发起请求后返回的json数据
这样就可以得到你想要的数据
Android简单版天气预报,显示天气预报(第二步)_第1张图片
Android简单版天气预报,显示天气预报(第二步)_第2张图片
那就先到这了,代码会在下一步开源

更多相关文章

  1. Android之解析Json数据
  2. Notification中Intent携带数据重复问题
  3. android中的数据存储
  4. ThreadLocal原理解析(1):数据存取
  5. Android--用JSON解析数据
  6. Android 中的数据存储
  7. android 直接进行数据库操作

随机推荐

  1. Android(安卓)jni调用第三方so库和.h文件
  2. Android中SQLite数据库存储方式 .(转)
  3. ubuntu下Qt之android环境配置以及一些常
  4. Android中Touch手势分发
  5. HTML iframe标签用法案例详解
  6. HTML DOM setInterval和clearInterval方
  7. 利用模糊实现视觉3D效果实例讲解
  8. sass 常用备忘案例详解
  9. 字符串和数组api操作学习实践
  10. 想做跨境电商,不会英语应该怎样入行?