Android项目中省市区联动的实现

来源:互联网 发布:网络歌曲谢谢你陪着我 编辑:程序博客网 时间:2024/06/06 00:15

最近项目中需要用户输入详细地址信息,省市区作为选项供用户选择,涉及到省市区信息的联动。


UI效果如下:


选择省,市的信息会自动更新,选择市,区县信息会自动更新。


整理好的省市区信息(以北京为例):

 <province name="北京市">    <city name="北京市">      <district name="昌平区" zipcode="100000" />      <district name="朝阳区" zipcode="100000" />      <district name="崇文区" zipcode="100000" />      <district name="大兴区" zipcode="100000" />      <district name="东城区" zipcode="100000" />      <district name="房山区" zipcode="100000" />      <district name="丰台区" zipcode="100000" />      <district name="海淀区" zipcode="100000" />      <district name="怀柔区" zipcode="100000" />      <district name="门头沟区" zipcode="100000" />      <district name="密云县" zipcode="100000" />      <district name="平谷区" zipcode="100000" />      <district name="石景山区" zipcode="100000" />      <district name="顺义区" zipcode="100000" />      <district name="通州区" zipcode="100000" />      <district name="西城区" zipcode="100000" />      <district name="宣武区" zipcode="100000" />      <district name="延庆县" zipcode="100000" />      <district name="其他" zipcode="100000" />    </city>  </province>

解析方式是SAX解析,优点是占用内存小,解析快,具体解析代码我也是参考了其他blog的方法,代码如下:

package com.mrwujay.cascade.service;    import java.util.ArrayList;  import java.util.List;  import org.xml.sax.Attributes;  import org.xml.sax.SAXException;  import org.xml.sax.helpers.DefaultHandler;    import com.mrwujay.cascade.model.CityModel;  import com.mrwujay.cascade.model.DistrictModel;  import com.mrwujay.cascade.model.ProvinceModel;    public class XmlParserHandler extends DefaultHandler {        /**      * 存储所有的解析对象      */      private List<ProvinceModel> provinceList = new ArrayList<ProvinceModel>();                  public XmlParserHandler() {                }        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 {      }    }  


其中,ProvinceModel的代码如下,两个参数,一个是该选项下的省市区名称,还有一个是该省市下一级列表。CityModel,DistrictModel类似:

package com.aitgou.zhixingou.model;import java.util.List;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;}@Overridepublic String toString() {return "ProvinceModel [name=" + name + ", cityList=" + cityList + "]";}}


初始化试图之后,就可以对联动信息进行初始化:

         /** * 解析省市区的XML数据 */protected void initProvinceDatas() {List<ProvinceModel> provinceList = null;AssetManager asset = getAssets();try {InputStream input = asset.open("province_data.xml");// 创建一个解析xml的工厂对象SAXParserFactory spf = SAXParserFactory.newInstance();// 解析xmlSAXParser parser = spf.newSAXParser();XmlParserHandler handler = new XmlParserHandler();parser.parse(input, handler);input.close();// 获取解析出来的数据provinceList = handler.getDataList();// 初始化默认选中的省、市、区if (provinceList != null && !provinceList.isEmpty()) {province = provinceList.get(0).getName();List<CityModel> cityList = provinceList.get(0).getCityList();if (cityList != null && !cityList.isEmpty()) {city = cityList.get(0).getName();List<DistrictModel> districtList = cityList.get(0).getDistrictList();district = districtList.get(0).getName();}}// */mProvinceDatas = new String[provinceList.size()];for (int i = 0; i < provinceList.size(); i++) {// 遍历所有省的数据mProvinceDatas[i] = provinceList.get(i).getName();List<CityModel> cityList = provinceList.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()];DistrictModel[] distrinctArray = new DistrictModel[districtList.size()];for (int k = 0; k < districtList.size(); k++) {// 遍历市下面所有区/县的数据DistrictModel districtModel = new DistrictModel(districtList.get(k).getName(),districtList.get(k).getZipcode());distrinctArray[k] = districtModel;distrinctNameArray[k] = districtModel.getName();}// 市-区/县的数据,保存到mDistrictDatasMapmDistrictDatasMap.put(cityNames[j], distrinctNameArray);}// 省-市的数据,保存到mCitisDatasMapmCitisDatasMap.put(provinceList.get(i).getName(), cityNames);}} catch (Throwable e) {e.printStackTrace();} finally {}}


点击省,显示下拉,选择省的名字,下拉菜单消失,同时程序根据这个省的名字,更新相应的市信息:

下拉的popwindow:

public CustomPopupWindow(Activity context, String[] test ,String key ,OnItemClickListener itemsOnClick) {super(context);LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);mMenuView = inflater.inflate(R.layout.popupwindow_custom, null);lv = (ListView) mMenuView.findViewById(R.id.popupwindow_custom_lv) ;adapter = new Popupwindows_Adapter(test, context, key) ;lv.setAdapter(adapter);lv.setOnItemClickListener(itemsOnClick);this.setContentView(mMenuView);this.setWidth(LayoutParams.MATCH_PARENT);this.setHeight(LayoutParams.MATCH_PARENT);this.setFocusable(true);this.setAnimationStyle(R.style.BrillPopupAnimation);ColorDrawable dw = new ColorDrawable(0x99000000);this.setBackgroundDrawable(dw);mMenuView.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubint height = mMenuView.findViewById(R.id.popup_layout).getTop();int y = (int) event.getY();if (event.getAction() == MotionEvent.ACTION_UP) {if (y < height) {dismiss();}}return true;}});}
popwindow中listview的adapter:

    public Popupwindows_Adapter(String[] date, Context context , String key) {this.date = date;this.key = key ;this.context = context;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn date.length;}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int arg0) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView(int arg0, View arg1, ViewGroup arg2) {// TODO Auto-generated method stubif (arg1 == null) {ViewHolder holder = new ViewHolder();arg1 = LayoutInflater.from(context).inflate(R.layout.popupwindow_custom_item, null);holder.popupwindow_tv = (TextView) arg1.findViewById(R.id.popupwindow_custom_item_tv);holder.popupwindow_iv = (ImageView) arg1.findViewById(R.id.popupwindow_custom_item_iv) ;arg1.setTag(holder);}ViewHolder holder = (ViewHolder) arg1.getTag();holder.popupwindow_tv.setText(date[arg0].toString());if(key.equals(date[arg0].toString())){holder.popupwindow_iv.setVisibility(View.VISIBLE);holder.popupwindow_tv.setTextColor(context.getResources().getColor(R.color.list_textcolor_blue));}else{holder.popupwindow_iv.setVisibility(View.INVISIBLE);holder.popupwindow_tv.setTextColor(context.getResources().getColor(R.color.funtion_textcolor));}return arg1;}class ViewHolder {private TextView popupwindow_tv;private ImageView popupwindow_iv ;}
item样式:





城市更新:

     /** * 根据当前的省,更新市的信息 */private void updateCities() {cities = mCitisDatasMap.get(province);if (cities == null) {cities = new String[] { "" };}}

区县更新:

     /** * 根据当前的市,更新区的信息 */private void updateAreas() {areas = mDistrictDatasMap.get(city);if (areas == null) {areas = new String[] { "" };}}


大致代码如上,如果要实现省市区三级联动的滚轮效果,可以参考这篇文章:http://blog.csdn.net/wulianghuan/article/details/41549189/








1 0
原创粉丝点击