您当前的位置: 首页 >  android

xiangzhihong8

暂无认证

  • 2浏览

    0关注

    1324博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

android仿iphone的地区选择

xiangzhihong8 发布时间:2015-02-12 07:47:05 ,浏览量:2

最近项目要做一个,类似淘宝手机客户端的,选择收货地址的三级联动滚动选择组件,下面是它的大致界面截图:

在IOS中有个叫UIPickerView的选择器,并且在dataSource中定义了UIPickerView的数据源和定制内容,所以用只要熟悉它的基本用法,要实现这么个三级联动滑动选择是挺简单的。 

言归正传,今天讨论的是在Android里面如何来实现这么个效果,那么如何实现呢??? 相信部分童鞋首先想到的是android.widget.DatePicker和android.widget.TimePicker,因为它们的样子长得很像,事实就是它们仅仅是长得相而已,Google在设计这个两个widget的时候,并没有提供对外的数据源适配接口,带来的问题就是,我们只能通过它们来选择日期和时间,至于为什么这样设计,如果有童鞋知道,请给我留言,Thanks~

DatePicker.class包含的方法截图:

 全都是关于时间获取用的方法.

好了,既然在Android中没办法偷懒的用一个系统widget搞定,那么只能自己来自定义view来实现了,这篇就围绕这个来展开分享一下,我在项目中实现这个的全过程。首先是做了下开源代码调研,在github上面有一个叫做 android-wheel 的开源控件, 代码地址https://github.com/maarek/android-wheel

是一个非常好用的组件,对于数据适配接口的抽取和事件的回调都做了抽取,代码的耦合度低,唯一不足就是在界面的定制这块,如果你需要做更改,需要去动源代码的。我这里在界面的代码做了改动,放在我的项目src目录下了:

在此次项目中,省市区及邮编的数据是放在了assets/province_data.xml里面,是产品经理花了好几天时间整理的,绝对是最齐全和完善了,辛苦辛苦!!!

关于XML的解析,一共有SAX、PULL、DOM三种解析方式,这里就不讲了,可以看我的前面的几篇学习的文章:

Android解析XML方式(一)使用SAX解析

Android解析XML方式(二)使用PULL解析XML

Android解析XML方式(三)使用DOM解析XML

此次项目中使用的是SAX解析方式,因为它占用内存少,并且速度快,数据解析代码写在了 com.mrwujay.cascade.service/XmlParserHandler.java中,代码如下:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.mrwujay.cascade.service;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import org.xml.sax.Attributes;  
  6. import org.xml.sax.SAXException;  
  7. import org.xml.sax.helpers.DefaultHandler;  
  8.   
  9. import com.mrwujay.cascade.model.CityModel;  
  10. import com.mrwujay.cascade.model.DistrictModel;  
  11. import com.mrwujay.cascade.model.ProvinceModel;  
  12.   
  13. public class XmlParserHandler extends DefaultHandler {  
  14.   
  15.     /** 
  16.      * 存储所有的解析对象 
  17.      */  
  18.     private List provinceList = new ArrayList();  
  19.             
  20.     public XmlParserHandler() {  
  21.           
  22.     }  
  23.   
  24.     public List getDataList() {  
  25.         return provinceList;  
  26.     }  
  27.   
  28.     @Override  
  29.     public void startDocument() throws SAXException {  
  30.         // 当读到第一个开始标签的时候,会触发这个方法  
  31.     }  
  32.   
  33.     ProvinceModel provinceModel = new ProvinceModel();  
  34.     CityModel cityModel = new CityModel();  
  35.     DistrictModel districtModel = new DistrictModel();  
  36.       
  37.     @Override  
  38.     public void startElement(String uri, String localName, String qName,  
  39.             Attributes attributes) throws SAXException {  
  40.         // 当遇到开始标记的时候,调用这个方法  
  41.         if (qName.equals("province")) {  
  42.             provinceModel = new ProvinceModel();  
  43.             provinceModel.setName(attributes.getValue(0));  
  44.             provinceModel.setCityList(new ArrayList());  
  45.         } else if (qName.equals("city")) {  
  46.             cityModel = new CityModel();  
  47.             cityModel.setName(attributes.getValue(0));  
  48.             cityModel.setDistrictList(new ArrayList());  
  49.         } else if (qName.equals("district")) {  
  50.             districtModel = new DistrictModel();  
  51.             districtModel.setName(attributes.getValue(0));  
  52.             districtModel.setZipcode(attributes.getValue(1));  
  53.         }  
  54.     }  
  55.   
  56.     @Override  
  57.     public void endElement(String uri, String localName, String qName)  
  58.             throws SAXException {  
  59.         // 遇到结束标记的时候,会调用这个方法  
  60.         if (qName.equals("district")) {  
  61.             cityModel.getDistrictList().add(districtModel);  
  62.         } else if (qName.equals("city")) {  
  63.             provinceModel.getCityList().add(cityModel);  
  64.         } else if (qName.equals("province")) {  
  65.             provinceList.add(provinceModel);  
  66.         }  
  67.     }  
  68.       
  69.     @Override  
  70.     public void characters(char[] ch, int start, int length)  
  71.             throws SAXException {  
  72.     }  
  73.   
  74. }  

通过XmlParserHandler.java提供的getDataList()方法获取得到,之后再进行拆分放到省、市、区不同的HashMap里面方便做数据适配。

这里是它的具体实现代码:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. protected void initProvinceDatas()  
  2.     {  
  3.         List provinceList = null;  
  4.         AssetManager asset = getAssets();  
  5.         try {  
  6.             InputStream input = asset.open("province_data.xml");  
  7.             // 创建一个解析xml的工厂对象  
  8.             SAXParserFactory spf = SAXParserFactory.newInstance();  
  9.             // 解析xml  
  10.             SAXParser parser = spf.newSAXParser();  
  11.             XmlParserHandler handler = new XmlParserHandler();  
  12.             parser.parse(input, handler);  
  13.             input.close();  
  14.             // 获取解析出来的数据  
  15.             provinceList = handler.getDataList();  
  16.             //*/ 初始化默认选中的省、市、区  
  17.             if (provinceList!= null && !provinceList.isEmpty()) {  
  18.                 mCurrentProviceName = provinceList.get(0).getName();  
  19.                 List cityList = provinceList.get(0).getCityList();  
  20.                 if (cityList!= null && !cityList.isEmpty()) {  
  21.                     mCurrentCityName = cityList.get(0).getName();  
  22.                     List districtList = cityList.get(0).getDistrictList();  
  23.                     mCurrentDistrictName = districtList.get(0).getName();  
  24.                     mCurrentZipCode = districtList.get(0).getZipcode();  
  25.                 }  
  26.             }  
  27.             //*/  
  28.             mProvinceDatas = new String[provinceList.size()];  
  29.             for (int i=0; i
关注
打赏
1482932726
查看更多评论
立即登录/注册

微信扫码登录

0.0689s