一、 准备数据
在网上找了一份xml的数据源,链接在这:http://pan.baidu.com/s/1pJoHosr
在res文件夹下新建一个xml文件夹,将解压得到的3个xml文件放进去。
二、 解析xml文件
先看一下xml文件吧,是这个格式的
<resources> <Province ID="0" ProvinceName="请选择">请选择 </Province>解析代码如下:
public ArrayList<Province> getProvincesInfo() { //设置xml解析器,为读取的数据创建ArrayList对象 XmlResourceParser xrp = getResources().getXml(R.xml.provinces); ArrayList<Province> provinces = new ArrayList<>(); try { int eventType = xrp.getEventType(); while (eventType != XmlResourceParser.END_DOCUMENT) { //当内容标签开始时,读取相应标签的属性 if (eventType == XmlResourceParser.START_TAG && xrp.getName().equals("Province")) { String id = xrp.getAttributeValue(null, "ID"); String name = xrp.getAttributeValue(null, "ProvinceName"); provinces.add(new Province(Integer.parseInt(id), name)); } eventType = xrp.next(); } } catch (XmlPullParserException | IOException e) { e.printStackTrace(); } xrp.close(); return provinces; }
三、绑定数据
将数据信息读到ArrayList对象中就好办了,直接用ArrayAdapter绑定就可以了://为控件绑定视图 Spinner spnProvince = (Spinner)findViewById(R.id.spnProvince); //读取并绑定province数据 final ArrayList<Province> provinces = getProvincesInfo(); final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,provinces); spnProvince.setAdapter(adapter);因为ArrayList对象中的数据为自定义的Province,在Spinner中显示时会调用toString()函数,所以要在Province中重写toString函数,返回省份名称。
城市、和区域的选择都要依赖于上级的信息,在读取城市信息的时候需要传入省份的ID,来获取对应的城市,可以在读取标签属性的时候,判断传入的PID与读取的PID是否相等,来获取城市列表。
四、设置监听,实现城市和区域选择
数据绑定玩之后,就要设置监听了。
省份数据,在Activity onCreate的时候读入;城市数据,在选择了省份之后读入;区域数据在选择了城市之后读入。设置spnProvince的监听如下,在监听中读取数据,初始化子控件:
//为Province设置监听 spnProvince.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //初始化城市列表 initSpnCity((int) id); //选中“请选择”时不设置地址显示 if (id == 0) { //清空City、District选项 strProvince = ""; strCity = ""; strDistrict = ""; } else { strProvince = provinces.get((int) id).getName(); } //显示选中的地址 tvAddress.setText(ADDRESS_TITLE + " " + strProvince + " " + strCity + " " + strDistrict); } @Override public void onNothingSelected(AdapterView<?> parent) { } });到此,三级地址选择就搞定了 效果图
下面是源码,Province、City、District的实现代码就不贴了,记得重写toString()方法返回名称就可以了。
package com.lcy.demo.studydemo; import android.content.res.XmlResourceParser; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Spinner; import android.widget.TextView; import com.lcy.demo.studydemo.address.City; import com.lcy.demo.studydemo.address.District; import com.lcy.demo.studydemo.address.Province; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; /** * Created by loucyin on 2015/10/8. */ public class SpinnerActivity extends AppCompatActivity { public static final String ADDRESS_TITLE = "您选择的地址是:"; TextView tvAddress; String strProvince = ""; String strCity = ""; String strDistrict = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_spinner); //绑定地址显示TextView tvAddress = (TextView)findViewById(R.id.tvAddress); //初始化spinner控件 initSpnProvince(); } //初始化spnProvince控件,并为其绑定数据,设置监听 public void initSpnProvince() { //为控件绑定视图 Spinner spnProvince = (Spinner)findViewById(R.id.spnProvince); //读取并绑定province数据 final ArrayList<Province> provinces = getProvincesInfo(); final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,provinces); spnProvince.setAdapter(adapter); //为Province设置监听 spnProvince.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //初始化城市列表 initSpnCity((int) id); //选中“请选择”时不设置地址显示 if (id == 0) { //清空City、District选项 strProvince = ""; strCity = ""; strDistrict = ""; } else { strProvince = provinces.get((int) id).getName(); } //显示选中的地址 tvAddress.setText(ADDRESS_TITLE + " " + strProvince + " " + strCity + " " + strDistrict); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); } //初始化spnCity,并为其绑定数据,设置监听 public void initSpnCity(int provinceId) { //为控件绑定视图 final Spinner spnCity = (Spinner)findViewById(R.id.spnCity); //读取并绑定province数据 final ArrayList<City> cities = getCitiesInfo(provinceId); ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,cities); spnCity.setAdapter(adapter); //为Province设置监听 spnCity.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //获取城市ID,并初始化区域列表 int cid = cities.get((int) id).getId(); initSpnDistrict(cid); //选中“请选择”时不设置地址显示 if(id == 0) { strCity = ""; strDistrict = ""; } else { strCity = cities.get((int) id).getName(); } //显示选中的地址 tvAddress.setText(ADDRESS_TITLE + " " + strProvince + " " + strCity + " " + strDistrict); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); } //初始化spnDistrict控件,绑定数据,设置监听 public void initSpnDistrict(int cityId) { //为控件绑定视图 final Spinner spnDistrict = (Spinner)findViewById(R.id.spnDistrict); //读取并绑定province数据 final ArrayList<District> districts = getDistrictInfo(cityId); ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,districts); spnDistrict.setAdapter(adapter); spnDistrict.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //选中“请选择”时不设置地址显示 if (id == 0) { strDistrict = ""; } else { strDistrict = districts.get((int) id).getName(); } //显示选中的地址 tvAddress.setText(ADDRESS_TITLE + " " + strProvince + " " + strCity + " " + strDistrict); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); } /** * @description 从文件中获取省份信息 * @return 返回省份的ArrayList对象 */ public ArrayList<Province> getProvincesInfo() { //设置xml解析器,为读取的数据创建ArrayList对象 XmlResourceParser xrp = getResources().getXml(R.xml.provinces); ArrayList<Province> provinces = new ArrayList<>(); try { int eventType = xrp.getEventType(); while (eventType != XmlResourceParser.END_DOCUMENT) { //当内容标签开始时,读取相应标签的属性 if (eventType == XmlResourceParser.START_TAG && xrp.getName().equals("Province")) { String id = xrp.getAttributeValue(null, "ID"); String name = xrp.getAttributeValue(null, "ProvinceName"); provinces.add(new Province(Integer.parseInt(id), name)); } eventType = xrp.next(); } } catch (XmlPullParserException | IOException e) { e.printStackTrace(); } xrp.close(); return provinces; } /** * @description 输入省份ID,获取对应的城市 * @param provinceId 省份ID,用于在选择其对应的城市 * @return 返回所包含城市的ArrayList对象 */ public ArrayList<City> getCitiesInfo(int provinceId) { //设置xml解析器,为读取的数据创建ArrayList对象 XmlResourceParser xrp = getResources().getXml(R.xml.cities); ArrayList<City> cities = new ArrayList<>(); cities.add(new City(0,0,"请选择","")); try { int eventType = xrp.getEventType(); while (eventType != XmlResourceParser.END_DOCUMENT) { //当内容标签开始时,读取相应标签的属性 if (eventType == XmlResourceParser.START_TAG && xrp.getName().equals("City")) { String pid = xrp.getAttributeValue(null, "PID"); if (provinceId == Integer.parseInt(pid)) { String id = xrp.getAttributeValue(null, "ID"); String zipCode = xrp.getAttributeValue(null, "ZipCode"); String name = xrp.getAttributeValue(null, "CityName"); cities.add(new City(Integer.parseInt(id), Integer.parseInt(pid), name, zipCode)); } } eventType = xrp.next(); } } catch (XmlPullParserException | IOException e) { e.printStackTrace(); } xrp.close(); return cities; } /** * @description 输入城市ID,获取对应的区域 * @param cityId 城市ID,用于在选择其对应的区域 * @return 返回所包含区域的ArrayList对象 */ public ArrayList<District> getDistrictInfo(int cityId) { //设置xml解析器,为读取的数据创建ArrayList对象 XmlResourceParser xrp = getResources().getXml(R.xml.districts); ArrayList<District> districts = new ArrayList<>(); districts.add(new District(0,0,"请选择")); try { int eventType = xrp.getEventType(); while (eventType != XmlResourceParser.END_DOCUMENT) { //当内容标签开始时,读取相应标签的属性 if (eventType == XmlResourceParser.START_TAG && xrp.getName().equals("District")) { String cid = xrp.getAttributeValue(null, "CID"); if (cityId == Integer.parseInt(cid)) { String id = xrp.getAttributeValue(null, "ID"); String name = xrp.getAttributeValue(null, "DistrictName"); districts.add(new District(Integer.parseInt(id), cityId, name)); } } eventType = xrp.next(); } } catch (XmlPullParserException | IOException e) { e.printStackTrace(); } xrp.close(); return districts; } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/material_grey_300"> <TextView android:layout_width="80dp" android:layout_height="50dp" android:textAppearance="?android:attr/textAppearanceMedium" android:text="省份:" android:id="@+id/textView" android:gravity="center_vertical|center_horizontal" android:textColor="@android:color/holo_red_light"/> <Spinner android:layout_width="fill_parent" android:layout_height="50dp" android:id="@+id/spnProvince" android:spinnerMode="dropdown"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/material_grey_100"> <TextView android:layout_width="80dp" android:layout_height="50dp" android:textAppearance="?android:attr/textAppearanceMedium" android:text="城市:" android:id="@+id/textView2" android:gravity="center_vertical|center_horizontal" android:textColor="@android:color/holo_blue_bright"/> <Spinner android:layout_width="fill_parent" android:layout_height="50dp" android:id="@+id/spnCity" android:spinnerMode="dropdown"/> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/material_grey_300"> <TextView android:layout_width="80dp" android:layout_height="50dp" android:textAppearance="?android:attr/textAppearanceMedium" android:text="区域:" android:id="@+id/textView3" android:gravity="center_vertical|center_horizontal" android:textColor="@android:color/holo_green_dark"/> <Spinner android:layout_width="fill_parent" android:layout_height="50dp" android:id="@+id/spnDistrict" android:spinnerMode="dropdown"/> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/Address" android:id="@+id/tvAddress" android:gravity="center_vertical" android:paddingLeft="15dp" android:paddingTop="20dp" android:paddingRight="20dp" android:paddingBottom="20dp" android:background="@color/material_grey_100" android:textColor="@android:color/holo_orange_dark"/> </LinearLayout>