案例——天气预报 菜鸟级别的我

来源:互联网 发布:财务d6软件好不好 编辑:程序博客网 时间:2024/06/05 02:06


在实际生活中,大多数的人会在手机中安装一个天气预报的软件,这些软件在获取天气信息时,都是通过解析XML文件得到的,我们就通过一个案例“天气预报”来演示如何解析XML文件。

一、创建程序

创建一个名为“天气预报”的应用程序,将包名修改为cn.edu.bzu,设计用户交互界面。解析天气预报程序对应的布局文件(activity_main.xml)如下所示:


<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@drawable/timg"    tools:context="cn.edu.bzu.weatherforecast.MainActivity">    <LinearLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/ll_btn"        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true"        android:orientation="horizontal">        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/city_bj"            android:text="北京"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/city_sh"            android:text="上海"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/city_jl"            android:text="吉林"/>    </LinearLayout>    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/select_city"        android:layout_alignParentTop="true"        android:layout_marginTop="34dp"        android:layout_toLeftOf="@+id/icon"        android:text="上海"        android:textSize="20sp"/>    <ImageView        android:layout_width="70dp"        android:layout_height="70dp"        android:id="@+id/icon"        android:src="@drawable/ic_launcher"        android:layout_alignLeft="@+id/ll_btn"        android:layout_below="@+id/select_city"        android:layout_marginTop="25dp"        android:paddingBottom="5dp"/>    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/select_weather"        android:layout_alignRight="@+id/icon"        android:layout_below="@+id/icon"        android:layout_marginRight="15dp"        android:layout_marginTop="18dp"        android:gravity="center"        android:text="多云"        android:textSize="18sp"/>    <LinearLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/linearLayout1"        android:layout_alignBottom="@+id/select_weather"        android:layout_marginBottom="10dp"        android:layout_alignRight="@+id/ll_btn"        android:gravity="center"        android:orientation="vertical">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/temp"            android:layout_marginTop="10dp"            android:layout_gravity="center_vertical"            android:text="-7℃ "            android:textSize="22sp"/>        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/wind"            android:text="风力:3级"            android:textSize="18sp"/>        <TextView            android:layout_width="73dp"            android:layout_height="wrap_content"            android:id="@+id/pm"            android:text="pm"            android:textSize="18sp"/>    </LinearLayout></RelativeLayout>


在上述布局文件中,底部放置了一个Linearlayout包含三个按钮,单击切换不同城市信息;左侧分别放置了两个TextView和一个ImageView,TextView分别显示城市和天气预报,图片显示当前天气;布局右侧放置了一个Linearlayout,里边包含三个TextView分别显示温度、风力和PM2.5值。


二、创建weather.xml文件

在工程src根目录中创建一个weather.xml文件,该文件中包含三个城市的天气信息,具体如下显示:


<?xml version="1.0" encoding="utf-8"?><infos>    <city id="1">        <temp>20℃/30℃</temp>        <weather>晴天多云</weather>        <name>上海</name>        <pm>80</pm>        <wind>1级</wind>    </city>    <city id="2">        <temp>26℃/32℃</temp>        <weather>晴天</weather>        <name>北京</name>        <pm>98</pm>        <wind>3级</wind>    </city>    <city id="3">        <temp>15℃/24℃</temp>        <weather>多云</weather>        <name>吉林</name>        <pm>30</pm>        <wind>5级</wind>    </city></infos>

上述xml文件主要包含了三个城市的天气预报,每一个城市都由id、temp、weather、name、pm和wind属性组成。


三、创建WeatherInfo类

从weather.xml代码中可以看出,每个城市天气信息都包含id、temp、weather、name、pm和wind属性,为了方便后续的使用,我们可以将这六个属性封装成一个JavaBean代码,具体如下:


public class WeatherInfo {    private int id;    private String name;    private String weather;    private String temp;    private String pm;    private String wind;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getWind() {        return wind;    }    public void setWind(String wind) {        this.wind = wind;    }    public String getPm() {        return pm;    }    public void setPm(String pm) {        this.pm = pm;    }    public String getWeather() {        return weather;    }    public void setWeather(String weather) {        this.weather = weather;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getTemp() {        return temp;    }    public void setTemp(String temp) {        this.temp = temp;    }}

上述代码一共封装了六个属性,分别对应XML文件中的是id、name、weather、temp、pm和wind。


四、创建WeatherService工具类

为了代码的更加易于阅读,避免大量代码都在一个类中,因此创建一个用来解析XML文件的工具类WeatherSerivice类中定义了一个getWeatherInfos()方法,该方法中包含了解析XML文件的逻辑代码。WeatherService具体代码如下:


public class WeatherService {    public static List<WeatherInfo>getWeatherInfos(InputStream is)throws Exception{        XmlPullParser parser= Xml.newPullParser();        parser.setInput(is,"utf-8");        List<WeatherInfo>weatherInfos=null;        WeatherInfo  weatherInfo=null;        int type=parser.getEventType();        while (type!=XmlPullParser.END_DOCUMENT){            switch (type){                case XmlPullParser.START_TAG:                        if ("infos".equals(parser.getName())){                            weatherInfos=new ArrayList<WeatherInfo>();                        }else if ("city".equals(parser.getName())){                            weatherInfo=new WeatherInfo();                            String idStr=parser.getAttributeValue(0);                            WeatherInfo.setId(Integer.parseInt(idStr));                        }else if ("temp".equals(parser.getName())){                            String temp=parser.nextText();                            weatherInfo.setTemp(temp);                        }else if ("weather".equals(parser.getName())){                            String weather=parser.nextText();                            weatherInfo.setWeather(weather);                        }else if ("name".equals(parser.getName())){                            String name=parser.nextText();                            weatherInfo.setName(name);                        }else if ("pm".equals(parser.getName())) {                            String pm = parser.nextText();                            weatherInfo.setPm(pm);                        } else if ("wind".equals(parser.getName())) {                            String wind = parser.nextText();                            weatherInfo.setWind(wind);                        }                    break;                case XmlPullParser.END_TAG:                    if ("city".equals(parser.getName())){                        weatherInfo.add(weatherInfo);                        weatherInfo=null;                    }                    break;            }            type=parser.next();        }        return weatherInfos;    }}

上述代码需要注意的是,type=parser.next();这行代码一定不能忘记,因为在while循环中,当一个节点信息解析完毕,会继续解析下一个节点,只有type的类型为END_DOCUMENT时才会结束循环,因此必须要把parser.next();获取到的类型赋值给type,不然会成为死循环。


五、编写界面交互代码(MainActivity)

在MainActivity中,调用WeatherService类中的getWeatherInfos()方法解析weather.xml文件,并将读取到的数据存入List<WeatherInfos>集合。然后遍历该集合中的每一条数据,最后将遍历到的数据显示在文本控件中,具体代码如下:


package cn.edu.bzu.weatherforecast;import android.app.Activity;import android.content.DialogInterface;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class MainActivity extends Activity implements View.OnClickListener {    private TextView select_city,select_weather,select_temp,select_wind,select_pm;    private Map<String,String>map;    private List<Map<String,String>>list;    private String temp,weather,name,pm,wind;    private ImageView icon;    protected void onCreate(Bundle savedInstanceState){        super.onCreate(savedInstanceState);        setContentView( R.layout.activity_main);        select_city=(TextView)findViewById(R.id.select_city);        select_weather=(TextView)findViewById(R.id.select_weather);        select_temp=(TextView)findViewById(R.id.temp);        select_wind=(TextView)findViewById(R.id.wind);        select_pm=(TextView)findViewById(R.id.pm);        icon=(ImageView)findViewById(R.id.icon);        findViewById(R.id.city_sh).setOnClickListener(this);        findViewById(R.id.city_bj).setOnClickListener(this);        findViewById(R.id.city_jl).setOnClickListener(this);        try {            List<WeatherInfo>infos=WeatherService.getWeatherInfos(MainActivity.class.getClassLoader().getResourceAsStream("weather.xml"));            list=new ArrayList<Map<String, String>>();            for (WeatherInfo info:infos){                map=new HashMap<String, String>();                map.put("temp",info.getTemp());                map.put("weather",info.getWeather());                map.put("name",info.getName());                map.put("pm",info.getPm());                map.put("wind",info.getWind());                list.add(map);            }        }catch (Exception e){            e.printStackTrace();            Toast.makeText(this,"解析信息失败",Toast.LENGTH_LONG).show();        }        getMap(1,R.drawable.sun);    }    public void onClick(View v){        switch (v.getId()){            case R.id.city_sh:                getMap(0,R.drawable.cloud_sun);                break;            case R.id.city_bj:                getMap(0,R.drawable.sun);                break;            case R.id.city_jl:                getMap(0,R.drawable.clouds);                break;        }    }    private void getMap(int number,int icon Number){        Map<String,String>bjMap=list.get(number);        temp=bjMap.get("temp");        weather=bjMap.get("weather");        name=bjMap.get("name");        pm=bjMap.get("pm");        wind=bjMap.get("wind");        select_city.setText(name);        select_weather.setText(weather);        select_temp.setText(""+temp);        select_wind.setText("风力 :"+wind);        select_pm.setText("pm:"+pm);        icon.setImageResource(iconNumber);    }}

上述代码第24行调用了WeatherSsrvice的解析XML文件方法,返回的是保存有天气信息的集合,然后把集合中的数据按照三个城市的信息分别放在不同的Map集合中,再把Map集合都存入List集合中。当我们点击按钮时,会触发getMap(int number,int icon Number)方法,三个不同的按钮会传进不同的int值用于List中对应的Map集合。最后从Map集合中把城市信息取出来分条展示在界面上。


六、运行程序查看天气

运行当前程序,分别选择城市“上海”“北京”,能看到结果。

做了两节课,最后应用没有成功运行出来,app显示shopping。所以没有图片了这次。