加载本地Xml文件实现省市区三级联动PopupWindows+ RecyclerView

项目需求要实现省市二级联动,因为一直没有定样式,所以一直没有开动,但是ios小伙伴先给搞定了,没办法就照着他的样式来写一个吧,

首先看下效果吧,没有加以美化选中效果....

加载本地Xml文件实现省市区三级联动PopupWindows+ RecyclerView_第1张图片


主要是用PopupWindows来实现了省市的二级联动,xml文件很齐全,就捎带把区也写了进去..但是没有实现,有兴趣的小伙伴可以挑战一下,有了之前的省联动市.应该很容易就实现三级联动了.

首先要把xml本地文件添加到项目中(花了两个币下载的真坑),新建一个assets文件夹把省市区文件放进去即可(后面我会上传的)

我们先开始解析这个省市区文件代码如下

 public void initProvinceDatas() {
        List 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 cityList = provinceList.get(0).getCitysList();
                if (cityList != null && !cityList.isEmpty()) {
                    mCurrentCityName = cityList.get(0).getCity();
                    List 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 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 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 provinceList = new ArrayList();

   public XmlParserHandler() {

   }

   public List 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());
      } else if (qName.equals("city")) {
         cityModel = new Citys();
         cityModel.setCity(attributes.getValue(0));
         cityModel.setCity_id(attributes.getValue(1));
         cityModel.setAreaList(new ArrayList());
      } 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 localName, 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

  没有点击之后的效果变化,有需要添加的朋友可以私密我774737414




你可能感兴趣的:(Android)