项目需求要实现省市二级联动,因为一直没有定样式,所以一直没有开动,但是ios小伙伴先给搞定了,没办法就照着他的样式来写一个吧,
主要是用PopupWindows来实现了省市的二级联动,xml文件很齐全,就捎带把区也写了进去..但是没有实现,有兴趣的小伙伴可以挑战一下,有了之前的省联动市.应该很容易就实现三级联动了.
首先要把xml本地文件添加到项目中(花了两个币下载的真坑),新建一个assets文件夹把省市区文件放进去即可(后面我会上传的)
public void initProvinceDatas() { List<Provinces> provinceList = null; AssetManager asset = activity.getAssets(); try { InputStream input = asset.open("province_data.xml"); // 创建一个解析xml的工厂对象 SAXParserFactory spf = SAXParserFactory.newInstance(); // 解析xml SAXParser parser = spf.newSAXParser(); XmlParserHandler handler = new XmlParserHandler(); parser.parse(input,handler); input.close(); // 获取解析出来的数据 provinceList = handler.getDataList(); //*/ 初始化默认选中的省、市、区 if (provinceList != null && !provinceList.isEmpty()) { mCurrentProviceName = provinceList.get(0).getProvince(); mCurrentProviceID = provinceList.get(0).getProvince_id(); List<Citys> cityList = provinceList.get(0).getCitysList(); if (cityList != null && !cityList.isEmpty()) { mCurrentCityName = cityList.get(0).getCity(); List<Area> districtList = cityList.get(0).getAreaList(); mCurrentDistrictName = districtList.get(0).getArea(); } } //*/ mProvinceDatas = new String[provinceList.size()]; mProvinceDatasID = new String[provinceList.size()]; for (int i = 0; i < provinceList.size(); i++) { // 遍历所有省的数据 mProvinceDatas[i] = provinceList.get(i).getProvince(); mProvinceDatasID[i] = provinceList.get(i).getProvince_id(); List<Citys> cityList = provinceList.get(i).getCitysList(); String[] cityNames = new String[cityList.size()]; String[] cityId = new String[cityList.size()]; for (int j = 0; j < cityList.size(); j++) { // 遍历省下面的所有市的数据 cityNames[j] = cityList.get(j).getCity(); cityId[j] = cityList.get(j).getCity_id(); List<Area> districtList = cityList.get(j).getAreaList(); String[] distrinctNameArray = new String[districtList.size()]; for (int k = 0; k < districtList.size(); k++) { // 遍历市下面所有区/县的数据 Area districtModel = new Area(districtList.get(k).getArea(),districtList.get(k).getArea_id()); // // 区/县对于的邮编,保存到mZipcodeDatasMap // mZipcodeDatasMap.put(districtList.get(k).getName(),districtList.get(k).getZipcode()); // distrinctArray[k] = districtModel; // distrinctNameArray[k] = districtModel.getName(); } // 市-区/县的数据,保存到mDistrictDatasMap mDistrictDatasMap.put(cityNames[j],distrinctNameArray); mDistrictDatasMap.put(cityId[j],distrinctNameArray); } // 省-市的数据,保存到mCitisDatasMap mCitisDatasMap.put(provinceList.get(i).getProvince(),cityNames); mCitisDatasIDMap.put(provinceList.get(i).getProvince(),cityId); } } catch (Throwable e) { e.printStackTrace(); } finally { } }
关于Xml解析可以查看下面资料 http://blog.csdn.net/wulianghuan/article/details/8613101 (使用SAX解析) http://blog.csdn.net/wulianghuan/article/details/8615271(使用PULL解析) http://blog.csdn.net/wulianghuan/article/details/8615617 (使用DOM解析)此次项目中使用的是SAX解析方式,因为它占用内存少,并且速度快,数据解析代码写在了 XmlParserHandler.Java中,代码如下:
package com.mostchh.scienceploatform.utils; import com.mostchh.scienceploatform.model.home.Area; import com.mostchh.scienceploatform.model.home.Citys; import com.mostchh.scienceploatform.model.home.Provinces; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import java.util.ArrayList; import java.util.List; public class XmlParserHandler extends DefaultHandler { /** * 存储所有的解析对象 */ private List<Provinces> provinceList = new ArrayList<Provinces>(); public XmlParserHandler() { } public List<Provinces> getDataList() { return provinceList; } @Override public void startDocument() throws SAXException { // 当读到第一个开始标签的时候,会触发这个方法 } Provinces provinceModel = new Provinces(); Citys cityModel = new Citys(); Area districtModel = new Area(); @Override public void startElement(String uri,String localName,String qName, Attributes attributes) throws SAXException { // 当遇到开始标记的时候,调用这个方法 if (qName.equals("province")) { provinceModel = new Provinces(); provinceModel.setProvince(attributes.getValue(0)); provinceModel.setProvince_id(attributes.getValue(1)); provinceModel.setCitysList(new ArrayList<Citys>()); } else if (qName.equals("city")) { cityModel = new Citys(); cityModel.setCity(attributes.getValue(0)); cityModel.setCity_id(attributes.getValue(1)); cityModel.setAreaList(new ArrayList<Area>()); } else if (qName.equals("district")) { districtModel = new Area(); districtModel.setArea(attributes.getValue(0)); // districtModel.setZipcode(attributes.getValue(1)); } } @Override public void endElement(String uri,String qName) throws SAXException { // 遇到结束标记的时候,会调用这个方法 if (qName.equals("district")) { cityModel.getAreaList().add(districtModel); } else if (qName.equals("city")) { provinceModel.getCitysList().add(cityModel); } else if (qName.equals("province")) { provinceList.add(provinceModel); } } @Override public void characters(char[] ch,int start,int length) throws SAXException { } }
然后是PopupWindows的xml文件我用两个RecyclerView来实现他们的联动效果.如果对PopupWindows和RecyclerView不熟悉的同学就去找找资料,在这就不赘述了...主要就是数据的适配,首先获得省级列表之后要对外释放一个接口给市级列表,然后在对市级列表进行相应的适配.把之前获得的省市MAp,当前省级名称都传过去.
/** * 点击省切换市区 */ @Override public void onPopProvinceItemClicked(int position) { cityPopWindowsAdaptersAdapter = new CityPopWindowsAdapter(activity); cityPopRecycler.setAdapter(cityPopWindowsAdaptersAdapter); mCurrentProviceName = mProvinceDatas[position]; mCurrentProviceID = mProvinceDatasID[position]; cityPopWindowsAdaptersAdapter.setData(mCitisDatasMap,mCurrentProviceName,this); }
要注意cityPopWindowsAdapter返回的list是
mCitisDatasMap.get(provinceStr).length
主要是参考了http://blog.csdn.net/wulianghuan/article/details/41549189/ 这篇博客,在此感谢,此片博客实现了Wheel滑动的省市区三级联动有需要的小伙伴可以去看看
我会专门写一个Demo上传便于小伙伴们查阅
Demo下载地址http://download.csdn.net/detail/hui9520/9736097