我们在写项目时,有时候会需要用到显示中国城市列表,区域列表甚至邮政编码等。比如我最近在做的就是在popwindow 显示中国城市,然后二级显示城市区域列表,还有就是收货地址,买票填写的地址等等,都需要省市区的联动。所有我这里直接写了个本地城市xml 数据解析的辅助类。至于滚轮实现城市联动会在以后介绍。
下面就是popwindow的一个例子,这里是介绍的是解析数据的方法。
1.首先需要一个中国省市的数据列表
2.开始解析xml 数据
代码上面都有具体的注释,我就不一一解释了。
2.1 准备相关的bean
//城市的bean
public class CityModel {
private String name;
private List<DistrictModel> districtList;
public CityModel() {
super();
}
public CityModel(String name, List<DistrictModel> districtList) {
super();
this.name = name;
this.districtList = districtList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<DistrictModel> getDistrictList() {
return districtList;
}
public void setDistrictList(List<DistrictModel> districtList) {
this.districtList = districtList;
}
@Override
public String toString() {
return "CityModel [name=" + name + ", districtList=" + districtList
+ "]";
}
}
//省份的bean
public class ProvinceModel {
private String name;
private List<CityModel> cityList;
public ProvinceModel() {
super();
}
public ProvinceModel(String name, List<CityModel> cityList) {
super();
this.name = name;
this.cityList = cityList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<CityModel> getCityList() {
return cityList;
}
public void setCityList(List<CityModel> cityList) {
this.cityList = cityList;
}
@Override
public String toString() {
return "ProvinceModel [name=" + name + ", cityList=" + cityList + "]";
}
}
//区域的bean
public class DistrictModel {
private String name;
private String zipcode;
public DistrictModel() {
super();
}
public DistrictModel(String name, String zipcode) {
super();
this.name = name;
this.zipcode = zipcode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
@Override
public String toString() {
return "DistrictModel [name=" + name + ", zipcode=" + zipcode + "]";
}
}
2.2 解析本地xml 数据
public class XmlParserHelper extends DefaultHandler {
/**
* 存储所有的解析对象
*/
private List<ProvinceModel> provinceList = new ArrayList<ProvinceModel>();
public XmlParserHelper() {
}
public List<ProvinceModel> getDataList() {
return provinceList;
}
@Override
public void startDocument() throws SAXException {
// 当读到第一个开始标签的时候,会触发这个方法
}
ProvinceModel provinceModel = new ProvinceModel();
CityModel cityModel = new CityModel();
DistrictModel districtModel = new DistrictModel();
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// 当遇到开始标记的时候,调用这个方法
if (qName.equals("province")) {
provinceModel = new ProvinceModel();
provinceModel.setName(attributes.getValue(0));
provinceModel.setCityList(new ArrayList<CityModel>());
} else if (qName.equals("city")) {
cityModel = new CityModel();
cityModel.setName(attributes.getValue(0));
cityModel.setDistrictList(new ArrayList<DistrictModel>());
} else if (qName.equals("district")) {
districtModel = new DistrictModel();
districtModel.setName(attributes.getValue(0));
districtModel.setZipcode(attributes.getValue(1));
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// 遇到结束标记的时候,会调用这个方法
if (qName.equals("district")) {
cityModel.getDistrictList().add(districtModel);
} else if (qName.equals("city")) {
provinceModel.getCityList().add(cityModel);
} else if (qName.equals("province")) {
provinceList.add(provinceModel);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
}
}
2.3 提供辅助类获取对应的省份城市区域等
/**
* 中国城市区域的辅助类
*/
public class ProvinceAreaHelper extends Presenter{
private static final String TAG = "ProvinceAreaHelper";
private Context mContext;
/**
* 所有省
*/
protected String[] mProvinceDatas;
/**
* key - 省 value - 市
*/
protected Map<String, String[]> mCitisDatasMap = new HashMap<String, String[]>();
/**
* key - 市 values - 区
*/
protected Map<String, String[]> mDistrictDatasMap = new HashMap<String, String[]>();
/**
* key - 区 values - 邮编
*/
protected Map<String, String> mZipcodeDatasMap = new HashMap<String, String>();
/**
* 当前省的名称
*/
protected String mCurrentProviceName;
/**
* 当前市的名称
*/
protected String mCurrentCityName;
/**
* 当前区的名称
*/
protected String mCurrentDistrictName ="";
/**
* 当前区的邮政编码
*/
protected String mCurrentZipCode ="";
public ProvinceAreaHelper(Context context){
mContext = context;
}
/**
* 解析省市区的XML数据
*/
public void initProvinceData(){
List<ProvinceModel> provinceModelList;
AssetManager assetManager = mContext.getAssets();
try {
InputStream input = assetManager.open("province_data.xml");
//创建一个解析xml 的工厂对象
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
XmlParserHelper xmlParserHelper = new XmlParserHelper();
//开始解析xml
parser.parse(input,xmlParserHelper);
input.close();
//获取解析出来的数据
provinceModelList = xmlParserHelper.getDataList();
//*/ 初始化默认选中的省、市、区
if (provinceModelList!= null && !provinceModelList.isEmpty()) {
mCurrentProviceName = provinceModelList.get(0).getName();
List<CityModel> cityList = provinceModelList.get(0).getCityList();
if (cityList!= null && !cityList.isEmpty()) {
mCurrentCityName = cityList.get(0).getName();
List<DistrictModel> districtList = cityList.get(0).getDistrictList();
mCurrentDistrictName = districtList.get(0).getName();
mCurrentZipCode = districtList.get(0).getZipcode();
}
}
if(provinceModelList!=null){
mProvinceDatas = new String[provinceModelList.size()];
// 遍历所有省的数据
for (int i=0; i< provinceModelList.size(); i++) {
mProvinceDatas[i] = provinceModelList.get(i).getName();
List<CityModel> cityList = provinceModelList.get(i).getCityList();
String[] cityNames = new String[cityList.size()];
// 遍历省下面的所有市的数据
for (int j=0; j< cityList.size(); j++) {
cityNames[j] = cityList.get(j).getName();
List<DistrictModel> districtList = cityList.get(j).getDistrictList();
String[] distrinctNameArray = new String[districtList.size()];
// 遍历市下面所有区/县的数据
for (int k=0; k<districtList.size(); k++) {
DistrictModel districtModel = new DistrictModel(districtList.get(k).getName(), districtList.get(k).getZipcode());
// 区/县对于的邮编,保存到mZipcodeDatasMap
mZipcodeDatasMap.put(districtList.get(k).getName(), districtList.get(k).getZipcode());
distrinctNameArray[k] = districtModel.getName();
}
// 市-区/县的数据,保存到mDistrictDatasMap
mDistrictDatasMap.put(cityNames[j], distrinctNameArray);
}
// 省-市的数据,保存到mCitisDatasMap
mCitisDatasMap.put(provinceModelList.get(i).getName(), cityNames);
}
}
}catch (Exception e){
Log.e(TAG, "解析省市区的XML数据 Exception=" + e.getMessage());
e.printStackTrace();
}
}
public String[] updateCities(String provinceName){
mCurrentProviceName = provinceName;
// String[] cities = mCitisDatasMap.get(mCurrentProviceName);
// if (cities == null) {
// cities = new String[] { "" };
// }
return mCitisDatasMap.get(provinceName);
}
public String[] updateAreas(String cityName){
mCurrentCityName = cityName;
// String[] areas = mDistrictDatasMap.get(mCurrentCityName);
//
// if (areas == null) {
// areas = new String[] { "" };
// }
return mDistrictDatasMap.get(cityName);
}
public String getmCurrentProviceName() {
return mCurrentProviceName;
}
public String getmCurrentCityName() {
return mCurrentCityName;
}
public String getmCurrentDistrictName() {
return mCurrentDistrictName;
}
public String getmCurrentZipCode() {
return mCurrentZipCode;
}
public String[] getmProvinceDatas() {
return mProvinceDatas;
}
@Override
public void onDestory() {
mProvinceDatas = null;
mCitisDatasMap = null;
mDistrictDatasMap = null;
}
}
2.4 调用helper 获取对应的数据
//初始化对应的helper
provinceAreaHelper = new ProvinceAreaHelper(getActivity());
//获取解析的数据
provinceAreaHelper.initProvinceData();
在provinceAreaHelper 可以自己根据对应的情况获取对应的方法.
provinceAreaHelper 主要的目的是将 获取的数据进行封装处理,不直接在activity中处理,分离出来。可以多处使用,还是就是滚轮的城市联动也可以使用这个helper ,更具具体的需求写具体get方法获取对应的数据就可以了。
3.城市列表下载地址
我把我本地的地址上传。
http://download.csdn.net/detail/android_freshman/9610225