載入本地Xml檔案實現省市區三級聯動PopupWindows+ RecyclerView
阿新 • • 發佈:2019-02-12
專案需求要實現省市二級聯動,因為一直沒有定樣式,所以一直沒有開動,但是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