请尊重他人的劳动成果,转载请注明出处:Android开发之解析XML并实现三级联动效果

    本实例主要应用XmlPullParser解析XML文档中的省市区,然后将数据绑定到Spinner上实现三级联动的效果。关于XmlPullParser的详解大家可以参考《Android开发之使用PULL解析和生成XML》一文。

    运行效果图:

    省市区三级联动

    省市区三级联动

    省市区三级联动

    程序代码:

    核心代码:

    1. <pre name="code" class="java">package com.jph.sevice;
    2. import java.io.InputStream;
    3. import java.util.ArrayList;
    4. import java.util.HashMap;
    5. import java.util.List;
    6. import java.util.Map;
    7. import org.xmlpull.v1.XmlPullParser;
    8. import android.os.Handler;
    9. import android.os.Message;
    10. import android.util.Xml;
    11. /**
    12. * 解析省、市、区xml
    13. * @author jph
    14. * Date:2014.09.25
    15. */
    16. public class PullProvince {
    17. public static final int PARSESUCCWSS=0x2001;
    18. private Handler handler;
    19. public PullProvince(Handler handler) {
    20. // TODO Auto-generated constructor stub
    21. this.handler=handler;
    22. }
    23. /**
    24. * 获取所有省份城市以及区
    25. * @author jph
    26. * Date:2014.09.25
    27. */
    28. public void getProvinces(final InputStream inStream) {
    29. new Thread(new Runnable() {
    30. @Override
    31. public void run() {
    32. // TODO Auto-generated method stub
    33. try {
    34. XmlPullParser pullParser = Xml.newPullParser();
    35. pullParser.setInput(inStream, "UTF-8");
    36. int event;
    37. event = pullParser.getEventType();
    38. Map<String, Map<String, List<String>>> provinces = new HashMap<String,
    39. Map<String, List<String>>>();// 省份
    40. Map<String, List<String>> cities=null;// 城市
    41. ArrayList<String> areaAll = null;
    42. String pName = "";// 省份名称
    43. String cName = "";// 城市名称
    44. String aName = "";// 地区名
    45. String targetName = "";// 当前节点的名称
    46. while (event != XmlPullParser.END_DOCUMENT) {
    47. targetName = pullParser.getName();
    48. switch (event) {
    49. case XmlPullParser.START_TAG:
    50. if ("province".equals(targetName)) {// 处理省份节点
    51. pName = pullParser.getAttributeValue(0);// 当前省份名
    52. cities=new HashMap<String, List<String>>();
    53. } else if ("city".equals(targetName)) {// 处理城市节点
    54. cName = pullParser.getAttributeValue(0);
    55. areaAll = new ArrayList<String>();// 地区
    56. } else if ("area".equals(targetName)) {// 处理地区节点
    57. aName = pullParser.getAttributeValue(0);
    58. }
    59. break;
    60. case XmlPullParser.END_TAG:
    61. if (targetName.equals("area")) {
    62. areaAll.add(aName);
    63. } else if (targetName.equals("city")) {
    64. cities.put(cName, areaAll);
    65. } else if (targetName.equals("province")) {
    66. provinces.put(pName, cities);
    67. }
    68. break;
    69. }
    70. event = pullParser.next();
    71. }
    72. Message message=new Message();
    73. message.obj=provinces;//将解析出的数据放到message中传给主线程
    74. message.what=PARSESUCCWSS;
    75. handler.sendMessage(message);//通知主线程数据解析完毕
    76. } catch (Exception e) {
    77. // TODO Auto-generated catch block
    78. e.printStackTrace();
    79. }
    80. }
    81. }).start();
    82. }
    83. }
    84.  

    Activity:

    1. <pre name="code" class="java">package com.jph.px;
    2. import java.io.InputStream;
    3. import java.util.List;
    4. import java.util.Map;
    5. import com.jph.sevice.PullProvince;
    6. import android.os.Bundle;
    7. import android.os.Handler;
    8. import android.os.Message;
    9. import android.app.Activity;
    10. import android.view.View;
    11. import android.widget.AdapterView;
    12. import android.widget.AdapterView.OnItemSelectedListener;
    13. import android.widget.ArrayAdapter;
    14. import android.widget.Spinner;
    15. import android.widget.Toast;
    16. /**
    17. * 省,市,区三级联动
    18. * @author jph
    19. * Date:2014.09.25
    20. */
    21. public class MainActivity extends Activity {
    22. private Spinner province,city,area;
    23. private Map<String, Map<String, List<String>>> data=null;
    24. /**当前的选择的省份**/
    25. private String currentProvince;
    26. /**当前的选择的城市**/
    27. private String currentCity;
    28. private PullProvince pullProvince;
    29. // /**当前的选择的区**/
    30. // private String currentArea;
    31. private Handler mHandler=new Handler(){
    32. @SuppressWarnings("unchecked")
    33. @Override
    34. public void handleMessage(Message msg) {
    35. // TODO Auto-generated method stub
    36. switch (msg.what) {
    37. case PullProvince.PARSESUCCWSS://数据解析完毕,加载数据
    38. data=(Map<String, Map<String, List<String>>>) msg.obj;
    39. initData();
    40. break;
    41. default:
    42. break;
    43. }
    44. super.handleMessage(msg);
    45. }
    46. };
    47. @Override
    48. protected void onCreate(Bundle savedInstanceState) {
    49. super.onCreate(savedInstanceState);
    50. setContentView(R.layout.activity_main);
    51. province=(Spinner)findViewById(R.id.province);
    52. city=(Spinner)findViewById(R.id.city);
    53. area=(Spinner)findViewById(R.id.area);
    54. pullProvince=new PullProvince(mHandler);
    55. InputStream inStream = this.getClass().getClassLoader().
    56. getResourceAsStream("province_city.xml");
    57. pullProvince.getProvinces(inStream);
    58. }
    59. /**
    60. * 初始化数据
    61. */
    62. private void initData(){
    63. if (data!=null) {
    64. String[]arrStrings= data.keySet().toArray(new String[0]);
    65. System.out.println(arrStrings);
    66. //将省份信息填充到 province Spinner
    67. province.setAdapter(new ArrayAdapter<String>(this,
    68. android.R.layout.simple_list_item_multiple_choice,arrStrings));
    69. currentProvince=getCurrentProvince();
    70. bindCityAdapter(currentProvince);
    71. currentCity=getCurrentCity();
    72. bindAreaAdapter(currentCity);
    73. setOnItemSelectedListener();
    74. }
    75. }
    76. private void bindAreaAdapter(String currentCity) {
    77. // TODO Auto-generated method stub
    78. //根据当前显示的城市将对应的区填充到area Spinner
    79. area.setAdapter(new ArrayAdapter<String>(this,
    80. android.R.layout.simple_list_item_multiple_choice,
    81. data.get(currentProvince).get(currentCity)));
    82. }
    83. private void bindCityAdapter(String currentProvince) {
    84. // TODO Auto-generated method stub
    85. //根据当前显示的省份将对应的城市填充到city Spinner
    86. city.setAdapter(new ArrayAdapter<String>(this,
    87. android.R.layout.simple_list_item_multiple_choice,data.
    88. get(currentProvince).keySet().toArray(new String[0])));
    89. }
    90. /**
    91. * 为Spinner设置监听器
    92. */
    93. private void setOnItemSelectedListener() {
    94. // TODO Auto-generated method stub
    95. province.setOnItemSelectedListener(new OnItemSelectedListener() {
    96. @Override
    97. public void onItemSelected(AdapterView<?> arg0, View arg1,
    98. int arg2, long arg3) {
    99. // TODO Auto-generated method stub
    100. currentProvince=getCurrentProvince();
    101. bindCityAdapter(currentProvince);
    102. }
    103. @Override
    104. public void onNothingSelected(AdapterView<?> arg0) {
    105. // TODO Auto-generated method stub
    106. }
    107. });
    108. city.setOnItemSelectedListener(new OnItemSelectedListener() {
    109. @Override
    110. public void onItemSelected(AdapterView<?> arg0, View arg1,
    111. int arg2, long arg3) {
    112. // TODO Auto-generated method stub
    113. currentCity=getCurrentCity();
    114. bindAreaAdapter(currentCity);
    115. }
    116. @Override
    117. public void onNothingSelected(AdapterView<?> arg0) {
    118. // TODO Auto-generated method stub
    119. }
    120. });
    121. area.setOnItemSelectedListener(new OnItemSelectedListener() {
    122. @Override
    123. public void onItemSelected(AdapterView<?> arg0, View arg1,
    124. int arg2, long arg3) {
    125. // TODO Auto-generated method stub
    126. Toast.makeText(MainActivity.this,area.getSelectedItem().toString(),
    127. Toast.LENGTH_SHORT).show();
    128. }
    129. @Override
    130. public void onNothingSelected(AdapterView<?> arg0) {
    131. // TODO Auto-generated method stub
    132. }
    133. });
    134. }
    135. /**获取当前选择的省份
    136. * @return String:当前选择的省份
    137. */
    138. private String getCurrentProvince() {
    139. // TODO Auto-generated method stub
    140. return province.getSelectedItem().toString();
    141. }
    142. /**获取当前选择的城市
    143. * @return String:当前选择的城市
    144. */
    145. private String getCurrentCity() {
    146. // TODO Auto-generated method stub
    147. return city.getSelectedItem().toString();
    148. }
    149. }
    150.  

    布局文件:

    1. <pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    2. xmlns:tools="http://schemas.android.com/tools"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent"
    5. android:orientation="vertical" >
    6. <Spinner android:id="@+id/province"
    7. android:layout_width="match_parent"
    8. android:layout_height="wrap_content"
    9. />
    10. <Spinner android:id="@+id/city"
    11. android:layout_width="match_parent"
    12. android:layout_height="wrap_content"/>
    13. <Spinner android:id="@+id/area"
    14. android:layout_width="match_parent"
    15. android:layout_height="wrap_content"/>
    16. <TextView android:id="@+id/tv"
    17. android:layout_width="wrap_content"
    18. android:layout_height="wrap_content"/>
    19. </LinearLayout>
    20.