Xml解析天气预告
public class MainActivity extends Activity {
private String TAG = "MainActivity";
private TextView text_main_info;
private Spinner spinner_main_provinces;
private ListView listView_main_weather;
// 以下定义的集合用来存放省的名称及拼音信息
private List<Map<String, String>> list_province_map = null;
// 以下定义的集合用来存放省的名称
private List<String> list_province_name = new ArrayList<String>();
// 以下定义的集合用来存放省的拼音
private List<String> list_province_py = new ArrayList<String>();
private String urlString = "http://flash.weather.com.cn/wmaps/xml/";
private boolean flag = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text_main_info = (TextView) findViewById(R.id.text_main_info);
spinner_main_provinces = (Spinner) findViewById(R.id.spinner_main_provinces);
listView_main_weather = (ListView) findViewById(R.id.listView_main_weather);
// 解析省的xml文件,获取到所有省的名称和省的拼音
list_province_map = getProvinceMsg();
for (int i = 0; i < list_province_map.size(); i++) {
list_province_name.add(list_province_map.get(i).get("quName"));
list_province_py.add(list_province_map.get(i).get("pyName"));
}
// 给Spinner中设置适配器
ArrayAdapter<String> proviceAdapter = new ArrayAdapter<String>(
MainActivity.this, android.R.layout.simple_dropdown_item_1line,
list_province_name);
spinner_main_provinces.setAdapter(proviceAdapter);
// 给Spinner设置监听器
spinner_main_provinces
.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
// 当spinner的item别选中时,执行异步任务访问网络,通过网络获取天气数据
@Override
public void onItemSelected(AdapterView<?> parent,
View view, int position, long id) {
String urlName = list_province_py.get(position);
if (flag) {
new MyTask(MainActivity.this).execute(urlString
+ urlName + ".xml");
} else {
Toast.makeText(MainActivity.this, "请选择省直辖市查看当地天气!",
5000).show();
flag = true;
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
// 异步任务,执行网络访问
class MyTask extends AsyncTask<String, Void, byte[]> {
private Context context;
private ProgressDialog pDialog = null;
public MyTask(Context context) {
this.context = context;
pDialog = new ProgressDialog(context);
pDialog.setIcon(R.drawable.ic_launcher);
pDialog.setMessage("数据加载中......");
}
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog.show();
}
@Override
protected byte[] doInBackground(String... params) {
BufferedInputStream bis = null;
HttpURLConnection httpConn = null;
ByteArrayOutputStream baos = null;
// 访问网络,通过网络获取url地址中的数据
try {
URL url = new URL(params[0]);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.connect();
if (httpConn.getResponseCode() == 200) {
baos = new ByteArrayOutputStream();
bis = new BufferedInputStream(httpConn.getInputStream());
byte[] buffer = new byte[256];
int c = 0;
while ((c = bis.read(buffer)) != -1) {
baos.write(buffer, 0, c);
baos.flush();
}
return baos.toByteArray();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(byte[] result) {
super.onPostExecute(result);
if (result != null) {
// 将网络访问返回的数据进行xml解析,解析后的数据放到list集合中
List<Map<String, String>> list = getCityWeather(result);
// 将list作为自定义适配器的参数,构建自定义适配器
BaseAdapter weatherAdapter = new MyAdapter(MainActivity.this,
list);
// 给listview设置适配器
listView_main_weather.setAdapter(weatherAdapter);
} else {
Toast.makeText(context, "网络访问异常!", 5000).show();
}
pDialog.dismiss();
}
}
// 解析资源xml目录下的xml文件,获取到省、直辖市的名称信息,将数据放到list集合中
public List<Map<String, String>> getProvinceMsg() {
try {
XmlResourceParser pullParser = getResources()
.getXml(R.xml.province);
List<Map<String, String>> list = null;
Map<String, String> map = null;
int event = pullParser.getEventType();
while (event != 1) {
Log.i(TAG, "==" + event);
String nodeName = pullParser.getName();
switch (event) {
case 0:
list = new ArrayList<Map<String, String>>();
break;
case 2:
if (nodeName.equals("city")) {
map = new HashMap<String, String>();
String quName = pullParser.getAttributeValue(0);
String pyName = pullParser.getAttributeValue(1);
map.put("quName", quName);
map.put("pyName", pyName);
list.add(map);
}
break;
}
event = pullParser.next();
}
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 将从网络获取到的字节数组作为参数传进方法中,利用xml解析,获取到其中的天气数据,将这些数据放到list集合中
public List<Map<String, String>> getCityWeather(byte[] data) {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser pullParser = factory.newPullParser();
pullParser.setInput(new ByteArrayInputStream(data), "UTF-8");
List<Map<String, String>> list = null;
Map<String, String> map = null;
int event = pullParser.getEventType();
while (event != 1) {
String nodeName = pullParser.getName();
switch (event) {
case 0:
list = new ArrayList<Map<String, String>>();
break;
case 2:
if (nodeName.equals("city")) {
map = new HashMap<String, String>();
for (int i = 0; i < pullParser.getAttributeCount(); i++) {
map.put(pullParser.getAttributeName(i),
pullParser.getAttributeValue(i));
}
list.add(map);
}
break;
}
event = pullParser.next();
}
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 自定义适配器,目的是给ListView加载数据
class MyAdapter extends BaseAdapter {
private Context context = null;
private List<Map<String, String>> list = null;
public MyAdapter(Context context, List<Map<String, String>> list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder mHolder;
if (convertView == null) {
mHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(
R.layout.item_listview_main_weather, parent, false);
mHolder.text_item_listview_cityname = (TextView) convertView
.findViewById(R.id.text_item_listview_cityname);
mHolder.text_item_listview_temp = (TextView) convertView
.findViewById(R.id.text_item_listview_temp);
mHolder.text_item_listview_stateDetailed = (TextView) convertView
.findViewById(R.id.text_item_listview_stateDetailed);
mHolder.text_item_listview_wind = (TextView) convertView
.findViewById(R.id.text_item_listview_wind);
mHolder.text_item_listview_humidity = (TextView) convertView
.findViewById(R.id.text_item_listview_humidity);
mHolder.imageView_item_listview_state1 = (ImageView) convertView
.findViewById(R.id.imageView_item_listview_state1);
mHolder.imageView_item_listview_state2 = (ImageView) convertView
.findViewById(R.id.imageView_item_listview_state2);
convertView.setTag(mHolder);
} else {
mHolder = (ViewHolder) convertView.getTag();
}
// 从list集合中整理数据
String cityname = list.get(position).get("cityname");
String temp = list.get(position).get("tem1") + "℃/"
+ list.get(position).get("tem2") + "℃";
String stateDetailed = list.get(position).get("stateDetailed");
String windString = list.get(position).get("windDir") + " "
+ list.get(position).get("windPower");
String humidity = list.get(position).get("humidity");
String state1 = list.get(position).get("state1");
String state2 = list.get(position).get("state2");
// 给获取到的天气数据赋值到item布局的指定控件中
mHolder.text_item_listview_cityname.setText(cityname);
mHolder.text_item_listview_temp.setText(temp);
mHolder.text_item_listview_stateDetailed.setText(stateDetailed);
mHolder.text_item_listview_wind.setText(windString);
mHolder.text_item_listview_humidity.setText(humidity);
// 如果天气数据中的state1和state2相同,则只保留一个imageView控件,隐藏另一个。
// 如果两个不同,则说明天气情况有转变。则两个ImageView都保留。
if (state1.equals(state2)) {
mHolder.imageView_item_listview_state1
.setImageResource(getImageId(state1));
mHolder.imageView_item_listview_state2
.setVisibility(View.INVISIBLE);
} else {
mHolder.imageView_item_listview_state1
.setImageResource(getImageId(state1));
mHolder.imageView_item_listview_state2
.setVisibility(View.VISIBLE);
mHolder.imageView_item_listview_state2
.setImageResource(getImageId(state2));
}
return convertView;
}
// 将自定义item布局中的控件定义成ViewHolder的属性
class ViewHolder {
private TextView text_item_listview_cityname;
private TextView text_item_listview_temp;
private TextView text_item_listview_stateDetailed;
private TextView text_item_listview_wind;
private TextView text_item_listview_humidity;
private ImageView imageView_item_listview_state1;
private ImageView imageView_item_listview_state2;
}
// 通过state1或state2的数据,组成图片名称,通过图片名称,找到在R.java文件中生成的id。
// 利用id可以通过ImageView的setImageResource()方法给ImageView控件加载图片。
public int getImageId(String state1) {
Class<R.drawable> cls = R.drawable.class;
try {
return cls.getDeclaredField("b_" + state1).getInt(null);
} catch (Exception e) {
e.printStackTrace();
return R.drawable.b_nothing;
}
}
}
}