1. 程式人生 > >載入本地Xml檔案實現省市區三級聯動PopupWindows+ RecyclerView

載入本地Xml檔案實現省市區三級聯動PopupWindows+ RecyclerView

專案需求要實現省市二級聯動,因為一直沒有定樣式,所以一直沒有開動,但是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解析可以檢視下面資料

此次專案中使用的是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 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

 我會專門寫一個Demo上傳便於小夥伴們查閱

  沒有點選之後的效果變化,有需要新增的朋友可以私密我774737414