**第三篇**

接下来我们在之前创立好的gson包下建立6个实体类分别为:AQI,Basic,Forecast,Now,Suggestion,Weather如下:
为了解析GSON返回来的数据

AQI代码为:

public class AQI {    public AQICity city;    public class AQICity    {        public String aqi;//空气质量指数        public String pm25;//pm25指数    }}

Basic代码为:
//JSON格式中的一些字段不太适合直接作为JAVA字段来命名,
//所以使用@SerializedName注解让JSON字段和java字段之间建立映射关系

public class Basic {    @SerializedName("city")    public String cityName;//城市名称    @SerializedName("id")    public String weatherId;//城市ID    public Update update;    public class Update{        @SerializedName("loc")        public String updateTime;//更新时的时间    }}

Forecast代码为:

public class Forecast {    public String date;    @SerializedName("tmp")    public Temperature temperature;    @SerializedName("cond")    public More more;    public class Temperature    {        public String max;        public String min;    }    public class More    {        @SerializedName("txt_d")        public String info;    }}

Now代码为:

public class Now {    @SerializedName("tmp")    public String temperature;//温度    @SerializedName("cond")    public More more;    public class More    {        @SerializedName("txt")        public String info;//温度的内容    }}

Suggestion代码为:

public class Suggestion {    @SerializedName("comf")    public Comfort comfort;    @SerializedName("cw")    public CarWash carWash;    public Sport sport;    public class Comfort    {        @SerializedName("txt")        public String info;    }    public class CarWash    {        @SerializedName("txt")        public String info;    }    public class Sport    {        @SerializedName("txt")        public String info;    }}

Weather代码为:

public class Weather {    public String status;    public Basic basic;    public AQI aqi;    public Now now;    public Suggestion suggestion;    @SerializedName("daily_forecast")    //由于daily_forecast中包含的是一个数组,索引这里引用了List集合来引用Forecast类    public List forecastList;}

实体类创建完成了,接下来我们建立一个WeatherActivity活动
由于要将所有的内容都在此界面显示,所有布局文件里的内容会很多而且复杂,所有我们采用分段形式,然后在activity_weather_activity.xml布局文件内统一添加进来
首先我们先建立一个标题栏title.xml布局文件
代码如下:
其中Button的背景图是我们事先下载好的

    

然后在新建一个now.xml布局文件
用于显示温度和天气信息
代码如下:

        

建立一个forecast.xml布局文件
用来显示未来几天的天气情况
代码如下:

            

建立一个forecast_item.xml布局文件
用来显示未来几天的天气情况的子布局文件
未来几天气信息的子项布局:
天气预报日期
天气概况
当天最高温度
当天最低温度

代码如下:

                

建立一个aqi.xml布局文件
用于显示空气质量指数
代码如下:

                                                                                                                                                             

建立一个suggestion.xml布局文件
用于显示官方建议,例如洗车,运动等
代码如下:

                

然后呢我们在activity_weather_activity.xml布局文件中将他们添加进来

DrawerLayout 滑动菜单
SwipeRefreshLayout 下拉刷新
android:fitsSystemWindows=“true” 为系统状态留出空间,不然会和自己的APP头部挤在一起
代码如下:

                                                                                                                                                                                                                    

然后我们util包下建立一个名为Utility的类,用于解析GSON数据
代码如下:

public class Utility {    /**     * 解析和处理服务器返回的省级数据     */    public static boolean handleProvinceResponse(String response)    {        if(!TextUtils.isEmpty(response))        {            try            {                JSONArray allProvinces = new JSONArray(response);                for (int i = 0; i < allProvinces.length(); i++)                {                    JSONObject provinceObject = allProvinces.getJSONObject(i);                    Province province = new Province();                    province.setProvinceName(provinceObject.getString("name"));                    province.setProvinceCode(provinceObject.getInt("id"));                    //调用save()方法将数据存储到数据库中                    province.save();                }                return true;            }catch (JSONException e)            {                e.printStackTrace();            }        }        return false;    }    /**     * 解析和处理服务器返回的市级数据     */    public static boolean handleCityResponse(String response, int provinceId)    {        if(!TextUtils.isEmpty(response))        {            try {                JSONArray allCities = new JSONArray(response);                for (int i = 0; i < allCities.length(); i++)                {                    JSONObject cityObject = allCities.getJSONObject(i);                    City city = new City();                    city.setCityName(cityObject.getString("name"));                    city.setCityCode(cityObject.getInt("id"));                    city.setProvinceId(provinceId);                    //调用save()方法将数据存储到数据库中                    city.save();                }                return true;            }catch (JSONException e)            {                e.printStackTrace();            }        }        return false;    }    /**     * 解析和处理服务器返回的县级数据     */    public static boolean handleCountyResponse(String response, int cityId)    {        if(!TextUtils.isEmpty(response))        {            try {                JSONArray allCounties = new JSONArray(response);                for (int i = 0; i < allCounties.length(); i++)                {                    JSONObject countyObject = allCounties.getJSONObject(i);                    County county = new County();                    county.setCountyName(countyObject.getString("name"));                    county.setWeatherId(countyObject.getString("weather_id"));                    county.setCityId(cityId);                    //调用save()方法将数据存储到数据库中                    county.save();                }                return true;            }catch (JSONException e)            {                e.printStackTrace();            }        }        return false;    }    /**     * 将返回的JSON数据解析成Weather实体类     */    public static Weather handleWeatherResponse(String response)    {        try {            JSONObject jsonObject = new JSONObject(response);            JSONArray jsonArray = jsonObject.getJSONArray("HeWeather");            String weatherContent = jsonArray.getJSONObject(0).toString();            return new Gson().fromJson(weatherContent,Weather.class);        }catch (Exception e)        {            e.printStackTrace();        }        return null;    }}

然后我们编写WeatherActivity里的代码,把信息显示出来
代码如下:

public class WeatherActivity extends AppCompatActivity {    public DrawerLayout drawerLayout;    private Button navButton;    public SwipeRefreshLayout swipeRefresh;    private String mWeatherId;    private ScrollView weatherLayout;    private TextView titleCity;    private TextView titleUpdateTime;    private TextView degreeText;    private TextView weatherInfoText;    private LinearLayout forecastLayout;    private TextView aqiText;    private TextView pm25Text;    private TextView comfortText;    private TextView carWashText;    private TextView sportText;    private ImageView bingPicImg;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_weather_activty);        //实现背景图和手机状态栏融合在一起,这个功能在Android5.0及以上的系统才支持,所以我们要做一个版本号的判断        if(Build.VERSION.SDK_INT >= 21)        {            //拿到当前活动的DecorView            View decorView = getWindow().getDecorView();            //调用它的setSystemUiVisibility()方法来改变系统UI的显示。            //这里传入View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN和View.SYSTEM_UI_FLAG_LAYOUT_STABLE就表示活动的布局会显示在状态栏上            decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);            //调用setStatusBarColor()方法将状态栏设置为透明色。            getWindow().setStatusBarColor(Color.TRANSPARENT);        }        //初始化各控件        bingPicImg = (ImageView)findViewById(R.id.bing_pic_img);        weatherLayout = (ScrollView)findViewById(R.id.weather_layout);        titleCity = (TextView)findViewById(R.id.title_city);        titleUpdateTime = (TextView)findViewById(R.id.title_update_time);        degreeText = (TextView)findViewById(R.id.degree_text);        weatherInfoText = (TextView)findViewById(R.id.weather_info_text);        forecastLayout = (LinearLayout) findViewById(R.id.forecast_layout);        aqiText = (TextView)findViewById(R.id.aqi_text);        pm25Text = (TextView)findViewById(R.id.pm25_text);        comfortText = (TextView)findViewById(R.id.comfort_text);        carWashText = (TextView)findViewById(R.id.car_wash_text);        sportText = (TextView)findViewById(R.id.sport_text);        swipeRefresh = (SwipeRefreshLayout)findViewById(R.id.swipe_refresh);        swipeRefresh.setColorSchemeResources(R.color.colorPrimary);        //滑动菜单功能        drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);        navButton = (Button)findViewById(R.id.nav_button);        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);        String weatherString = prefs.getString("weather",null);        if(weatherString != null)        {            //有缓存时直接解析天气数据            Weather weather = Utility.handleWeatherResponse(weatherString);            showWeatherInfo(weather);            mWeatherId = weather.basic.weatherId;        }else        {            //无缓存时去服务器查询天气            mWeatherId = getIntent().getStringExtra("weather_id");            // String weatherId = getIntent().getStringExtra("weather_id");            weatherLayout.setVisibility(View.INVISIBLE);            //requestWeather(weatherId);            requestWeather(mWeatherId);        }        //下拉刷新        swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()        {            @Override            public void onRefresh()            {                requestWeather(mWeatherId);            }        });        //按钮点击事件滑动菜单        navButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                //打开滑动菜单                drawerLayout.openDrawer(GravityCompat.START);            }        });       String bingPic = prefs.getString("bing_pic",null);        if(bingPic != null)        {            Glide.with(this).load(bingPic).into(bingPicImg);        }        else        {            loadBingPic();        }    }    /**     * 根据天气id请求城市天气信息     */    public void requestWeather(final String weatherId)    {        String weatherUrl = "http://guolin.tech/api/weather?cityid=" + weatherId + "&key=6f6b5169b08547f483d662d4e8c5d591";        HttpUtil.sendOkHttpRequest(weatherUrl, new Callback() {            @Override            public void onFailure(@NotNull Call call, @NotNull IOException e) {                e.printStackTrace();                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        Toast.makeText(WeatherActivity.this,"获取天气信息失败hahaha",Toast.LENGTH_SHORT).show();                        swipeRefresh.setRefreshing(false);                    }                });            }            @Override            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {                final String responseText = response.body().string();                final Weather weather = Utility.handleWeatherResponse(responseText);                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        if(weather != null && "ok".equals(weather.status))                        {                            SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();                            editor.putString("weather",responseText);                            editor.apply();                            mWeatherId = weather.basic.weatherId;                            showWeatherInfo(weather);                        }                        else                        {                            Toast.makeText(WeatherActivity.this,"获取天气信息失败nonono",Toast.LENGTH_SHORT).show();                        }                        swipeRefresh.setRefreshing(false);                    }                });            }        });        loadBingPic();    }    /**     * 加载必应每日一图     */    private void loadBingPic()    {        String requestBingPic = "http://guolin.tech/api/bing_pic";        HttpUtil.sendOkHttpRequest(requestBingPic, 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 {                final String bingPic = response.body().string();                SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();                editor.putString("bing_pic",bingPic);                editor.apply();                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        Glide.with(WeatherActivity.this).load(bingPic).into(bingPicImg);                    }                });            }        });    }    /**     * 处理并展示Weather实体类的数据     */    private void showWeatherInfo(Weather weather)    {        String cityName = weather.basic.cityName;        String updateTime = weather.basic.update.updateTime.split(" ")[1];        String degree = weather.now.temperature + "℃";        String weatherInfo = weather.now.more.info;        titleCity.setText(cityName);        titleUpdateTime.setText(updateTime);        degreeText.setText(degree);        weatherInfoText.setText(weatherInfo);        forecastLayout.removeAllViews();        for (Forecast forecast : weather.forecastList)        {            View view = LayoutInflater.from(this).inflate(R.layout.forecast_item,forecastLayout,false);            TextView dateText = (TextView)view.findViewById(R.id.date_text);            TextView infoText = (TextView)view.findViewById(R.id.info_text);            TextView maxText = (TextView)view.findViewById(R.id.max_text);            TextView minText = (TextView)view.findViewById(R.id.min_text);            dateText.setText(forecast.date);            infoText.setText(forecast.more.info);            maxText.setText(forecast.temperature.max);            minText.setText(forecast.temperature.min);            forecastLayout.addView(view);        }        if(weather.aqi != null)        {            aqiText.setText(weather.aqi.city.aqi);            pm25Text.setText(weather.aqi.city.pm25);        }        String comfort = "舒适度:" + weather.suggestion.comfort.info;        String carWash = "洗车指数:" + weather.suggestion.carWash.info;        String sport = "运动建议:" + weather.suggestion.sport.info;        comfortText.setText(comfort);        carWashText.setText(carWash);        sportText.setText(sport);        weatherLayout.setVisibility(View.VISIBLE);        Intent intent = new Intent(this, AutoUpdateService.class);        startService(intent);    }}

最后我们在MainActivity里加入一个判断缓存数据
代码如下:

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);        if(prefs.getString("weather",null) != null)        {            Intent intent = new Intent(this, WeatherActivity.class);            startActivity(intent);            finish();        }    }}

到这里天气预报就算你告一段落了,下面我们看一下效果:

选定城市后就可以看见界面了
背景图采用必应的接口,所有每天会有不同的背景


点击左上角的小房子图标可以切换城市

更多相关文章

  1. Android(安卓)实现json网络数据通过BaseAdapter加载到ListView中
  2. 编写android jni代码时遇到的问题
  3. 获取Android的Java源代码并在Eclipse中关联查看
  4. Android(安卓)支持的度量单位
  5. 告别Dagger2模板代码:DaggerAndroid原理解析
  6. 获取Android的Java源代码并在Eclipse中关联查看
  7. Android开发实战-项目学习笔记(1)
  8. 性能优化之Java(Android)代码优化
  9. 一步一步学习androidNDK编程(java给c传递数据)

随机推荐

  1. EditText属性详解
  2. 【Android(安卓)应用开发】 Ubuntu 安装
  3. android 模拟抢红包 原理
  4. Android——init.rc脚本
  5. 探讨android图片资源的抖动处理和格式转
  6. Android中ExpandableListView控件基本使
  7. 小记初学android过程中遇到的小问题(andro
  8. Android的用户界面
  9. Android--学习笔记--02--AndroidStudio的
  10. 解决Cygwin中的“died waiting for dll l