根据酷鸥天气改编的一个区域性的城市天气预报

1.本程序采用和风天气的免费API获取天气数据,在http://guolin.tech/api/weather/register上注册就可免费获取天气信息,天气信息以json的形式返回给我们。故先创建一个json的包用于对json数据的解析,代码如下:
在这里插入图片描述
注意:由于一时粗心,API类应该是获取天气中的AQI指数的,此处并不影响。
API类:

public class API {

    public APICity city; 
    public class APICity {    
        public String aqi;
        public String pm25;
    }
    }

Basic类:

public class Basic {

    @SerializedName("city")
    public String cityName;

    @SerializedName("cid")
    public String weatherId;

    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 API aqi;
    public Now now;
    public Suggestion suggestion;

    @SerializedName("daily_forecast")
    public List<Forecast> forecastList;
}

注意:上述代码中的 @SerializedName(""),括号中的属性是由网站中json数据得来的,千万不要出错,不然会拿不到数据。

2.创建一个util包用于写与服务器交互的相关类:
在这里插入图片描述
其中HttpUilt使用okhttp和服务器交互,只要传入相应的请求地址即可进行交互,代码如下:

public class HttpUilt {
	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);
		}
}

而Utility则是用于解析json数据的方法,代码如下:

public class Utility {
  public static Weather handleWeatherResponce(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;
 }
}

3.然后便可以编写布局,由于信息较多,我们在json包中可知我们只用到了现在的天气,预报的天气,空气质量和生活建议。因此我们在布局中使用FrameLayout并在其中嵌套一个ScrollView,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/a">

    <ScrollView
        android:id="@+id/weather_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="none"
        android:overScrollMode="never">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <include layout="@layout/title"/>
            <include layout="@layout/now"/>
            <include layout="@layout/forecast"/>
            <include layout="@layout/api"/>
            <include layout="@layout/suggestion"/>
        </LinearLayout>

    </ScrollView>
</FrameLayout>

其他子项布局和郭霖大神的书上一致。

布局后的样式如下:
在这里插入图片描述
这里我插入了一张南昌的图片,因为本程序仅能获取南昌的天气。

4.最后便是MianActivity的代码,首先定义初始化使用到的各个控件;

public class WeatherActivity extends AppCompatActivity {
    private ScrollView weatherLayout;
    private TextView titleUpdateTime;
    private TextView degreeText;
    private TextView weatherInfoText;
    private LinearLayout forecastLayout;
    private TextView apiText;
    private TextView pm25Text;
    private TextView comfortText;
    private TextView carWashText;
    private TextView sportText;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_weather);
        weatherLayout=(ScrollView)findViewById(R.id.weather_layout);
        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);
        apiText=(TextView)findViewById(R.id.api_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);
        requestWeather();
    }
}

上述代码最后一行的requestWeather方法为获取天气信息的一个方法,定义requestWeather函数,用于传入对应的接口地址,并调用HttpUtil.sendOkHttpRequest()向该地址发出请求,得到的json数据调用handleWeatherResponse将数据转换为Weather对象。注意,此处的weathterUrl的网址是我注册和风天气免费api获取的到的网址,cityid指的是南昌市的城市id,后面的key是我注册所得的key,可以拿到相应的天气。代码如下:

public void requestWeather(){
    String weatherUrl="http://guolin.tech/api/weather?cityid=CN101240101&key=94df6ecbe100465db73349525a29bef3 ";
    HttpUilt.sendOkHttpRequest(weatherUrl, new Callback() {
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            String responseText = response.body().string();
            System.out.println("responseText:"+responseText);
            final Weather weather= Utility.handleWeatherResponce(responseText);
            runOnUiThread(new Runnable() {

                public void run() {
                    if(weather!=null&&"ok".equals(weather.status)){
                        showWeatherInfo(weather);
                    }else{
                        Toast.makeText(WeatherActivity.this,"获取天气信息失败1",Toast.LENGTH_SHORT).show();
                    }
                }

            });
        }

        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
            runOnUiThread(new Runnable() {

                public void run() {
                    Toast.makeText(WeatherActivity.this,"获取天气信息失败",Toast.LENGTH_SHORT).show();
                }

            });
        }
    });
}

6.编写showWeatherInfo函数,将解析好的天气数据进行显示,更新各个控件的内容,代码如下:

private void showWeatherInfo(Weather weather){
    String updateTime="更新时间:"+weather.basic.update.updateTime.split(" ")[1];
    String degree=weather.now.temperature+"℃";
    String weatherInfo=weather.now.more.info;
    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){
        apiText.setText(weather.aqi.city.aqi);
        pm25Text.setText(weather.aqi.city.pm25);
    }
    comfortText.setText("舒适度:"+weather.suggestion.comfort.info);
    carWashText.setText("洗车指数:"+weather.suggestion.carWash.info);
    sportText.setText("运动建议:"+weather.suggestion.sport.info);
    weatherLayout.setVisibility(View.VISIBLE);
}

7.最后别忘了加上网络依赖,在AndroidManifest.xml中加上:

<uses-permission android:name="android.permission.INTERNET" />

还有在build.gradle(app)中添加依赖,这里我们只要添加okhttp和json的依赖就好:

compile 'com.squareup.okhttp3:okhttp:3.9.0'
    compile 'com.google.code.gson:gson:2.7'

8.最后运行代码,效果如下:

在这里插入图片描述
在这里插入图片描述
可以看到我们拿到天气内容,成功了。如果像要获取其他地区的天气预报,只要修改MainActivity中的requestWeather方法,把cityid改成对应城市的即可。

猜你喜欢

转载自blog.csdn.net/weixin_43728163/article/details/84862501