1. 程式人生 > >Android開發之解析XML並實現三級聯動效果

Android開發之解析XML並實現三級聯動效果

       本例項主要應用XmlPullParser解析XML文件中的省市區,然後將資料繫結到Spinner上實現三級聯動的效果。關於XmlPullParser的詳解大家可以參考《Android開發之使用PULL解析和生成XML》一文。

執行效果圖:

省市區三級聯動省市區三級聯動省市區三級聯動

程式程式碼:

核心程式碼:

<pre name="code" class="java">package com.jph.sevice;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.xmlpull.v1.XmlPullParser;
import android.os.Handler;
import android.os.Message;
import android.util.Xml;

/**
 * 解析省、市、區xml
 * @author jph
 * Date:2014.09.25
 */
public class PullProvince {	
	public static final int PARSESUCCWSS=0x2001;
	private Handler handler;
	public PullProvince(Handler handler) {
		// TODO Auto-generated constructor stub
		this.handler=handler;
	}
	/**
	 * 獲取所有省份城市以及區	
	 * @author jph
	 * Date:2014.09.25	
	 */
	public void getProvinces(final InputStream inStream) {			
		new Thread(new Runnable() {			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					XmlPullParser pullParser = Xml.newPullParser();
					pullParser.setInput(inStream, "UTF-8");
					int event;
						event = pullParser.getEventType();
					Map<String, Map<String, List<String>>> provinces = new HashMap<String, 
							Map<String, List<String>>>();// 省份
					Map<String, List<String>> cities=null;// 城市		
					ArrayList<String> areaAll = null;
					String pName = "";// 省份名稱
					String cName = "";// 城市名稱
					String aName = "";// 地區名
					String targetName = "";// 當前節點的名稱
					while (event != XmlPullParser.END_DOCUMENT) {
						targetName = pullParser.getName();
						switch (event) {
						case XmlPullParser.START_TAG:
							if ("province".equals(targetName)) {// 處理省份節點				
								pName = pullParser.getAttributeValue(0);// 當前省份名
								cities=new HashMap<String, List<String>>();
							} else if ("city".equals(targetName)) {// 處理城市節點				
								cName = pullParser.getAttributeValue(0);
								areaAll = new ArrayList<String>();// 地區
							} else if ("area".equals(targetName)) {// 處理地區節點
								aName = pullParser.getAttributeValue(0);
							}
							break;
						case XmlPullParser.END_TAG:
							if (targetName.equals("area")) {
								areaAll.add(aName);
							} else if (targetName.equals("city")) {
								cities.put(cName, areaAll);
							} else if (targetName.equals("province")) {
								provinces.put(pName, cities);
							}
							break;
						}
						event = pullParser.next();
					}
					Message message=new Message();					
					message.obj=provinces;//將解析出的資料放到message中傳給主執行緒
					message.what=PARSESUCCWSS;
					handler.sendMessage(message);//通知主執行緒資料解析完畢
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}		
			}
		}).start();		
	}
}

Activity:
<pre name="code" class="java">package com.jph.px;

import java.io.InputStream;
import java.util.List;
import java.util.Map;
import com.jph.sevice.PullProvince;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
/**
 * 省,市,區三級聯動
 * @author jph
 * Date:2014.09.25
 */
public class MainActivity extends Activity {
	private Spinner province,city,area;	
	private Map<String, Map<String, List<String>>> data=null;
	/**當前的選擇的省份**/
	private	String currentProvince;
	/**當前的選擇的城市**/
	private	String currentCity;
	private PullProvince pullProvince;	
//	/**當前的選擇的區**/
//	private	String currentArea;
	private Handler mHandler=new Handler(){
		@SuppressWarnings("unchecked")
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			switch (msg.what) {
			case PullProvince.PARSESUCCWSS://資料解析完畢,載入資料
				data=(Map<String, Map<String, List<String>>>) msg.obj;
				initData();
				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		province=(Spinner)findViewById(R.id.province);
		city=(Spinner)findViewById(R.id.city);
		area=(Spinner)findViewById(R.id.area);	
		pullProvince=new PullProvince(mHandler);
		InputStream inStream = this.getClass().getClassLoader().
				getResourceAsStream("province_city.xml");		
	    pullProvince.getProvinces(inStream);			
	}	
	/**
	 * 初始化資料
	 */
	private void initData(){		
		if (data!=null) {
			String[]arrStrings= data.keySet().toArray(new String[0]);
			System.out.println(arrStrings);			
			//將省份資訊填充到 province Spinner
			province.setAdapter(new ArrayAdapter<String>(this, 
					android.R.layout.simple_list_item_multiple_choice,arrStrings));
			currentProvince=getCurrentProvince();	
			bindCityAdapter(currentProvince);
			currentCity=getCurrentCity();			
			bindAreaAdapter(currentCity);			
			setOnItemSelectedListener();			
		}
	}
	private void bindAreaAdapter(String currentCity) {
		// TODO Auto-generated method stub
		//根據當前顯示的城市將對應的區填充到area Spinner		
		area.setAdapter(new ArrayAdapter<String>(this, 
				android.R.layout.simple_list_item_multiple_choice,
				data.get(currentProvince).get(currentCity)));
	}
	private void bindCityAdapter(String currentProvince) {
		// TODO Auto-generated method stub
		//根據當前顯示的省份將對應的城市填充到city Spinner
		city.setAdapter(new ArrayAdapter<String>(this, 
				android.R.layout.simple_list_item_multiple_choice,data.
				get(currentProvince).keySet().toArray(new String[0])));
	}
	/**
	 * 為Spinner設定監聽器
	 */
	private void setOnItemSelectedListener() {
		// TODO Auto-generated method stub
		province.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				// TODO Auto-generated method stub
				currentProvince=getCurrentProvince();
				bindCityAdapter(currentProvince);
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// TODO Auto-generated method stub
				
			}
		});
		city.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				// TODO Auto-generated method stub
				currentCity=getCurrentCity();
				bindAreaAdapter(currentCity);
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// TODO Auto-generated method stub
				
			}
		});
		area.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				// TODO Auto-generated method stub
				Toast.makeText(MainActivity.this,area.getSelectedItem().toString(), 
						Toast.LENGTH_SHORT).show();	
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// TODO Auto-generated method stub
				
			}
		});	
	}

	/**獲取當前選擇的省份
	 * @return String:當前選擇的省份
	 */
	private String getCurrentProvince() {
		// TODO Auto-generated method stub
		return province.getSelectedItem().toString();
	}
	/**獲取當前選擇的城市
	 * @return String:當前選擇的城市
	 */
	private String getCurrentCity() {
		// TODO Auto-generated method stub
		return city.getSelectedItem().toString();
	}
}

佈局檔案:
<pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
	<Spinner android:id="@+id/province"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    />
	<Spinner android:id="@+id/city"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"/>
	<Spinner android:id="@+id/area"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"/>
	<TextView android:id="@+id/tv"
	    android:layout_width="wrap_content"
	    android:layout_height="wrap_content"/>
</LinearLayout>