很早之前看淘宝就有了ios那种的城市选择控件,当时也看到网友有分享,不过那个写的很烂,后来(大概是去年吧),我们公司有这么一个项目,当时用的还是网上比较流行的那个黑框的那个,感觉特别的丑,然后我在那个开源的wheelview的基础上做封装,用户只需要专心数据的组装即可,然后填充就行,其他的可以不必考虑。

先上下效果图

接下来说下我的思路:网络请求-数据返回-设置数据-数据填充控件

接下来直接按上面的流程直接上代码:

网络请求我用的本地的json数据

 String address = Utils.readAssert(this, "address.txt");
        AddressModel model = JsonUtil.parseJson(address, AddressModel.class);

然后我们将本地的数据通过InputStream转换为String,并用过Gson将String映射到Model对象中

<span style="font-size:18px;"> public static String readAssert(Context context,  String fileName){
        String jsonString="";
        String resultString="";
        try {
            InputStream inputStream=context.getResources().getAssets().open(fileName);
            byte[] buffer=new byte[inputStream.available()];
            inputStream.read(buffer);
            resultString=new String(buffer,"utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultString;
    }</span>

接下来我们写自定义的Popwindos实现选择城市的弹框

<span style="font-size:18px;">public class ChooseAddressWheel implements MyOnWheelChangedListener {

    @Bind(R.id.province_wheel)
    MyWheelView provinceWheel;
    @Bind(R.id.city_wheel)
    MyWheelView cityWheel;
    @Bind(R.id.district_wheel)
    MyWheelView districtWheel;

    private Activity context;
    private View parentView;
    private PopupWindow popupWindow = null;
    private WindowManager.LayoutParams layoutParams = null;
    private LayoutInflater layoutInflater = null;

    private List<AddressDtailsEntity.ProvinceEntity> province = null;

    private OnAddressChangeListener onAddressChangeListener = null;

    public ChooseAddressWheel(Activity context) {
        this.context = context;
        init();
    }

    private void init() {
        layoutParams = context.getWindow().getAttributes();
        layoutInflater = context.getLayoutInflater();
        initView();
        initPopupWindow();
    }

    private void initView() {
        parentView = layoutInflater.inflate(R.layout.choose_city_layout, null);
        ButterKnife.bind(this, parentView);

        provinceWheel.setVisibleItems(7);
        cityWheel.setVisibleItems(7);
        districtWheel.setVisibleItems(7);

        provinceWheel.addChangingListener(this);
        cityWheel.addChangingListener(this);
        districtWheel.addChangingListener(this);
    }

    private void initPopupWindow() {
        popupWindow = new PopupWindow(parentView, WindowManager.LayoutParams.MATCH_PARENT, (int) (Utils.getScreenHeight(context) * (2.0 / 5)));
        popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        popupWindow.setAnimationStyle(R.style.anim_push_bottom);
        popupWindow.setBackgroundDrawable(new BitmapDrawable());
        popupWindow.setOutsideTouchable(false);
        popupWindow.setFocusable(true);
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            public void onDismiss() {
                layoutParams.alpha = 1.0f;
                context.getWindow().setAttributes(layoutParams);
                popupWindow.dismiss();
            }
        });
    }

    private void bindData() {
        provinceWheel.setViewAdapter(new ProvinceWheelAdapter(context, province));
        updateCitiy();
        updateDistrict();
    }

    @Override
    public void onChanged(MyWheelView wheel, int oldValue, int newValue) {
        if (wheel == provinceWheel) {
            updateCitiy();//省份改变后城市和地区联动
        } else if (wheel == cityWheel) {
            updateDistrict();//城市改变后地区联动
        } else if (wheel == districtWheel) {
        }
    }

    private void updateCitiy() {
        int index = provinceWheel.getCurrentItem();
        List<AddressDtailsEntity.ProvinceEntity.CityEntity> citys = province.get(index).City;
        if (citys != null && citys.size() > 0) {
            cityWheel.setViewAdapter(new CityWheelAdapter(context, citys));
            cityWheel.setCurrentItem(0);
            updateDistrict();
        }
    }

    private void updateDistrict() {
        int provinceIndex = provinceWheel.getCurrentItem();
        List<ProvinceEntity.CityEntity> citys = province.get(provinceIndex).City;
        int cityIndex = cityWheel.getCurrentItem();
        List<ProvinceEntity.AreaEntity> districts = citys.get(cityIndex).Area;
        if (districts != null && districts.size() > 0) {
            districtWheel.setViewAdapter(new AreaWheelAdapter(context, districts));
            districtWheel.setCurrentItem(0);
        }

    }

    public void show(View v) {
        layoutParams.alpha = 0.6f;
        context.getWindow().setAttributes(layoutParams);
        popupWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0);
    }

    public void setProvince(List<ProvinceEntity> province) {
        this.province = province;
        bindData();
    }

    public void defaultValue(String provinceStr, String city, String arae) {
        if (TextUtils.isEmpty(provinceStr)) return;
        for (int i = 0; i < province.size(); i++) {
            ProvinceEntity provinces = province.get(i);
            if (provinces != null && provinces.Name.equalsIgnoreCase(provinceStr)) {
                provinceWheel.setCurrentItem(i);
                if (TextUtils.isEmpty(city)) return;
                List<ProvinceEntity.CityEntity> citys = provinces.City;
                for (int j = 0; j < citys.size(); j++) {
                    ProvinceEntity.CityEntity cityEntity = citys.get(j);
                    if (cityEntity != null && cityEntity.Name.equalsIgnoreCase(city)) {
                        cityWheel.setViewAdapter(new CityWheelAdapter(context, citys));
                        cityWheel.setCurrentItem(j);
                        if (TextUtils.isEmpty(arae)) return;
                        List<ProvinceEntity.AreaEntity> areas = cityEntity.Area;
                        for (int k = 0; k < areas.size(); k++) {
                            ProvinceEntity.AreaEntity areaEntity = areas.get(k);
                            if (areaEntity != null && areaEntity.Name.equalsIgnoreCase(arae)) {
                                districtWheel.setViewAdapter(new AreaWheelAdapter(context, areas));
                                districtWheel.setCurrentItem(k);
                            }
                        }
                    }
                }
            }
        }
    }

    @OnClick(R.id.confirm_button)
    public void confirm() {
        if (onAddressChangeListener != null) {
            int provinceIndex = provinceWheel.getCurrentItem();
            int cityIndex = cityWheel.getCurrentItem();
            int areaIndex = districtWheel.getCurrentItem();

            String provinceName = null, cityName = null, areaName = null;

            List<ProvinceEntity.CityEntity> citys = null;
            if (province != null && province.size() > provinceIndex) {
                ProvinceEntity provinceEntity = province.get(provinceIndex);
                citys = provinceEntity.City;
                provinceName = provinceEntity.Name;
            }
            List<ProvinceEntity.AreaEntity> districts = null;
            if (citys != null && citys.size() > cityIndex) {
                ProvinceEntity.CityEntity cityEntity = citys.get(cityIndex);
                districts = cityEntity.Area;
                cityName = cityEntity.Name;
            }

            if (districts != null && districts.size() > areaIndex) {
                ProvinceEntity.AreaEntity areaEntity = districts.get(areaIndex);
                areaName = areaEntity.Name;
            }

            onAddressChangeListener.onAddressChange(provinceName, cityName, areaName);
        }
        cancel();
    }

    @OnClick(R.id.cancel_button)
    public void cancel() {
        popupWindow.dismiss();
    }

    public void setOnAddressChangeListener(OnAddressChangeListener onAddressChangeListener) {
        this.onAddressChangeListener = onAddressChangeListener;
    }</span>

然后通过三个Adapter去设置值,这里展示一个

<span style="font-size:18px;">public class ProvinceWheelAdapter extends BaseWheelAdapter<AddressDtailsEntity.ProvinceEntity> {
	public ProvinceWheelAdapter(Context context, List<AddressDtailsEntity.ProvinceEntity> list) {
		super(context,list);
	}

	@Override
	protected CharSequence getItemText(int index) {
		AddressDtailsEntity.ProvinceEntity data = getItemData(index);
		if(data != null){
			return data.Name;
		}
		return null;
	}
}</span>

那么在我们的页面中我们怎么用呢?

我们先初始化:

<span style="font-size:18px;">private void init() {
        initWheel();
        initData();
    }</span>
 <span style="font-size:18px;">private void initWheel() {
        chooseAddressWheel = new ChooseAddressWheel(this);
        chooseAddressWheel.setOnAddressChangeListener(this);
    }</span>

接下来设置值了

<span style="font-size:18px;">private void initData() {
        String address = Utils.readAssert(this, "address.txt");
        AddressModel model = JsonUtil.parseJson(address, AddressModel.class);
        if (model != null) {
            AddressDtailsEntity data = model.Result;
            if (data == null) return;
            chooseAddress.setText(data.Province + " " + data.City + " " + data.Area);
            if (data.ProvinceItems != null && data.ProvinceItems.Province != null) {
                chooseAddressWheel.setProvince(data.ProvinceItems.Province);
                chooseAddressWheel.defaultValue(data.Province, data.City, data.Area);
            }
        }
    }</span>

好了,就写到这里了,有需要的请加我们的群:278792776或者188716429
最后附上代码下载地址:
https://github.com/xiangzhihong/wheelview-master

android wheelview实现三级城市选择的更多相关文章

  1. Android之自定义控件-城市选择

    实现效果: 图片素材:           --> 首先, 城市数据字节放在 Json 文件, 就不网络获取了. city.json 存放 Json 数据: { "result&quo ...

  2. 【Android开源库】美团等APP城市选择

    CityPicker 现在使用比较多的类似美团等APP的城市选择界面. 2步即可实现,就是这么简单粗暴! Gif image APK 下载demo.apk体验. Install Gradle: com ...

  3. android 城市选择

    我们在开发过程中兰冕会有选着城市地点等东西,这些都是常用的东西,所以我也就将他封装起来了先来看看效果吧 1.首先看下项目的结构: 2.看下整体的项目效果 三:主ativity private Cont ...

  4. layui省市区三级联动城市选择

    基于layui框架制作精美的省市区下拉框三级联动菜单选择, 支持三级联动城市选择,点击提交获取选中值代码. 示例图如下: 资源链接: https://pan.baidu.com/s/1s6l8iDBE ...

  5. Python 练习:三级菜单选择城市(二)

    优化了上一个三级菜单选择城:http://www.cnblogs.com/klvchen/p/8646466.html info = { 'GuangDong':{ 'GuangZhou': ['Ti ...

  6. ionic-基于angularjs实现的多级城市选择组件

    大家都知道在移动端的选择地区组件,大部分都是模拟IOS选择器做的城市三级联动,但是在IOS上比较好,在Android上因为有的不支持ion-scroll.所以就会出现滚动不会自动回滚到某一个的正中间. ...

  7. 纯原生js移动端城市选择插件

    接着上一篇纯js移动端日期选择插件,话说今天同事又来咨询省市县联动的效果在移动端中如何实现,还是老样子,百度上一搜,诶~又全是基于jquery.zepto的,更加可恨的是大多数都是PC版的,三个sel ...

  8. mpvue微信小程序多列选择器用法:实现省份城市选择

    前言 微信小程序默认给我们提供了一个省市区的picker选择器,只需将mode设置为region即可 <picker mode="region" bindchange=&qu ...

  9. vue仿京东省市区三级联动选择组件

    工作中需要一个盒京东购物车地址选择相似的一个省市区三级联动选择组件,google查了下都是下拉框形式的,于是自己写了一个,希望对使用vue开发项目的朋友有帮助,显示效果如下:使用vue2.0开发 ht ...

随机推荐

  1. 关于Windows下程序执行的说明

    估计有很多人首次都是通过Windows(微软的操作系统)来使用计算机的,Windows的设计导致很多人认为所有程序只要双击一下就可以被正确执行了,所以一大堆初学程序设计的童鞋就会遇到些疑问: 为什么双 ...

  2. Android逆向工程

    在Root前提下,我们可以使用Hooker方式绑定so库,通过逆向方式篡改数值,从而达到所谓破解目的.然而,目前无论是软件加固方式,或是数据处理能力后台化,还是客户端数据真实性验证,都有了一定积累和发 ...

  3. Shell脚本生成网页版相册浏览器

    今天学到了一招,那就是使用脚本制作一款网页版相册浏览器.先上图吧. 必备基础 操作系统: 以linux为内核的操作系统都行 编程语言:Shell(bash)脚本,相关基础知识即可 下载工具:wget ...

  4. ROS常用三維機器人仿真工具Gazebo教程匯總

    參考網址: 1. http://gazebosim.org/tutorials 2. http://gazebosim.org/tutorials/browse Gazebo Tutorials Ga ...

  5. SSH网上商城---需求分析+表关系分析

    SSH---小编初次接触的时候傻傻的以为这个跟SHE有什么关系呢?又是哪路明星歌手,后来才知道小编又土鳖了,原来SSH是这个样子滴,百度百科对她这样阐述,SSH即 Spring + Struts +H ...

  6. 如何禁止App在后台运行以及如何保存和恢复App的状态

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 如果禁止App在后台运行 iOS上的App类似于Windows ...

  7. Android ClassLoader详解

    我们知道不管是插件化还是组件化,都是基于系统的ClassLoader来设计的.只不过Android平台上虚拟机运行的是Dex字节码,一种对class文件优化的产物,传统Class文件是一个Java源码 ...

  8. 【Netty源码学习】入门示例

    Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速开发高性能.高可靠性的网络服务器和客户端程序.        也就是说,Netty ...

  9. Hadoop:Hadoop基本命令

    http://blog.csdn.net/pipisorry/article/details/51223877 常用命令 启用hadoop start-dfs.sh start-hbase.sh 停止 ...

  10. FFmpeg API 变更记录

    最近一两年内FFmpeg项目发展的速度很快,本来是一件好事.但是随之而来的问题就是其API(接口函数)一直在发生变动.这么一来基于旧一点版本的FFmpeg的程序的代码在最新的类库上可能就跑不通了. 例 ...