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>
				
时间: 2024-10-12 21:33:56

Android开发之解析XML并实现三级联动效果的相关文章

Android开发pool解析xml

xml在开发中的作用不可小觑,很多时候我们都要用到这种文件,所以学习它的解析方式很是必要. 我们都知道java中xml的解析有:dom,SAX,但是Android下我们使用pool解析,是更为方便,而且有专门的api可以使用. dom:一次加载到内存,生成一个树状结构,消耗的内存较大 SAX:基于事件,速度快,效率高,不能回退. 1,首先我们需要定义出来解析器,它的定义方式,是通过Xml new出来的,这点要记着. XmlPullParser parser = Xml.newPullParser

【Android进阶】解析XML文件之使用DOM解析器

在前面的文章中,介绍了使用SAX解析器对XML文件进行解析,SAX解析器的优点就是占用内存小.这篇文章主要介绍使用DOM解析器对XML文件进行解析.DOM解析器的优点可能是理解起来比较的直观,当然,每个人对不同的解析方法可能有不同的喜好.但是DOM解析器有个比较大的缺点,就是占用内存比较多,在Android中的XML解析中,还是更推荐其他的解析方式. 下面介绍使用DOM解析器对XML进行解析. 下面是我们需要解析的xml文件 <?xml version="1.0" encodin

Android网络下解析XML

XML(Extensible Markup Language)可拓展标记语言,它与HTML一样,都是SGML(标准通用标记语言),它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言. 它非常适合万维网传输,提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据.在Android下有三种方式解析XML,分别为SAX.DOM.PULL:它们有各自的特点,在网络编程中会经常使用,根据实际情况选择哪一种解析方式. 1.内存占用 由于Android手机性能相对于PC还是

Android开发AlertDialog解析

打开源码,首先映入眼帘的是三个构造方法,但这三个构造方法都是protected类型的, 可见,不允许我们直接实例化AlertDialog. 因此,我们再看别的有没有方法.可以实例化 再仔细一看,发现一个变量 , AlertController mAlert; 这个才是我们今天的主角,重点研究它. mAlert的定义是在 ,以上我们提到的AlertDialog的构造函数, 此外,我们还发现,AlertDialog中几乎所有的方法都是通过这个mAlert变量来操作的, 也就是说,AlertDialo

android 通过pull解析xml文件

1 package com.example.xmldemo.test; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileNotFoundException; 6 import java.io.FileOutputStream; 7 import java.io.IOException; 8 import java.io.InputStreamReader; 9 import java.

Android 创建与解析XML(五)—— Dom4j方式

分享一下我老师大神的人工智能教程吧.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net 1.Dom4j概述 dom4j is an easy to use, open source library for working with XML, XPath and XSLT on the Java platform using the Java Collections Framework and with full sup

Android开发之自定义HorizontalScrollView视图实现仿ViewPager效果

开发过程中,需要达到 HorizontalScrollView和ViewPager的效果,于是直接重写了HorizontalScrollView来达到实现ViewPager的效果. 实际效果图如下: (1)自定义HorizontalScrollView类:AppHorizontalScrollView实现: package com.czm.ui.view; import java.util.ArrayList; import android.content.Context; import and

自写日期年月日三级联动效果jquery插件

哈哈,好久没写新博文啦,原因是最近一直在研究用jquery UI实现截取头像的功能,哈哈 言归正传,有时候呢,我们会在用户资料的页面用到一个年月日日期的三级联动效果.在网上找了找,没看到有多么合适的(主要是本屌丝倾向于用jquery写成插件的形式使用,哈哈~~) 这篇博文呢,主要目的是给大家看下我用jquery写成插件的形式. 原理很简单,就是判断闰年,然后在select change事件的时候给显示日期的select重新append option (PS.不知道为啥,js有appendchil

Android开发系列之XML解析

 xml文件存储是常用的数据存储方式,xml解析常用的有SAX解析.DOM解析.PULL解析等.本篇讲述xml的格式,xml的写入方式以及xml的解析.   .xml格式 <cartons> <carton id="1"> <name>天空之城</name> <maker>宫崎骏</maker> <style>冒险</style> <date>1986年8月2日</date