利用PickerView完成地址选择器(省市二级联动)

今天我们来说一个非常好用的框架PickerView,来完成地址选择器的功能。还是老原则不好用,不推荐。先上个效果图。
1.首先我们来做准备工作。
添加依赖

compile 'com.contrarywind:Android-PickerView:3.2.5'
//里面有用到gson,如果原来项目中有无需添加gson
compile 'com.google.code.gson:gson:2.3.1'

添加gson的混淆

##---------------Begin: proguard configuration for Gson  ----------
# Gson 代码混淆
-keepattributes Signature
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.daiba.wsjr.bean.** { *; }

##---------------End: proguard configuration for Gson  ----------

在main文件夹下创建assets的文件夹用于放保存地址数据的json文件city.json。city.json文件里的内容会附在最后。效果如下。


这里写图片描述

然后免费送一个将json文件里的数据转换成json字符串的类。需要贴在项目里的偶。

public class GetJsonDataUtil {


    public String getJson(Context context, String fileName) {

        StringBuilder stringBuilder = new StringBuilder();
        try {
            AssetManager assetManager = context.getAssets();
            BufferedReader bf = new BufferedReader(new InputStreamReader(
                    assetManager.open(fileName)));
            String line;
            while ((line = bf.readLine()) != null) {
                stringBuilder.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }
}

最后在贴一个承载城市数据的类。

public class CityBean implements IPickerViewData {

    /**
     * province : 北京
     * city_list : ["北京"]
     */

    private String province;
    private List city_list;

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public List getCity_list() {
        return city_list;
    }

    public void setCity_list(List city_list) {
        this.city_list = city_list;
    }

    @Override
    public String getPickerViewText() {
        return this.province;
    }
}

然后我们切入正题,先做好声明,省的你们粘完代码报错了,又说我都是按你的写的啊怎么报错呢?┭┮﹏┭┮

private ArrayList options1Items = new ArrayList<>();
    private ArrayList> options2Items = new ArrayList<>();
    private ArrayList>> options3Items = new ArrayList<>();
    private ArrayList bankNameList = new ArrayList<>();
    private Thread thread;
    private static final int MSG_LOAD_DATA = 0x0001;
    private static final int MSG_LOAD_SUCCESS = 0x0002;
    private static final int MSG_LOAD_FAILED = 0x0003;
    private boolean isLoaded = false;
    private String province;
    private String city;
    private TextView bank_addr;

因为我们要加载json文件中的数据,这属于耗时操作需要一个子线程,数据加载完毕才能让选择器展示数据。这里免我们用到了Handle解决这个问题。
(往方法区粘就行)

//判断地址数据是否获取成功
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_LOAD_DATA:
                    if (thread==null){//如果已创建就不再重新创建子线程了
                        Log.i("addr","地址数据开始解析");
                        thread = new Thread(new Runnable() {
                            @Override
                            public void run() {
                                // 写子线程中的操作,解析省市区数据
                                initJsonData();
                            }
                        });
                        thread.start();
                    }
                    break;

                case MSG_LOAD_SUCCESS:
                    Log.i("addr","地址数据获取成功");
                    isLoaded = true;
                    break;

                case MSG_LOAD_FAILED:
                    Log.i("addr","地址数据获取失败");
                    break;

            }
        }
    };

下面的是刚才用到的解析数据的工具类

 private void initJsonData() {//解析数据

        /**
         * 注意:assets 目录下的Json文件仅供参考,实际使用可自行替换文件
         * 关键逻辑在于循环体
         *
         * */
        String CityData = new GetJsonDataUtil().getJson(this,"city.json");//获取assets目录下的json文件数据

        ArrayList jsonBean = parseData(CityData);//用Gson 转成实体

        /**
         * 添加省份数据
         *
         * 注意:如果是添加的JavaBean实体,则实体类需要实现 IPickerViewData 接口,
         * PickerView会通过getPickerViewText方法获取字符串显示出来。
         */
        options1Items = jsonBean;

        for (int i=0;i CityList = new ArrayList<>();//该省的城市列表(第二级)
            ArrayList> Province_AreaList = new ArrayList<>();//该省的所有地区列表(第三极)

            for (int c=0; c parseData(String result) {//Gson 解析
        ArrayList detail = new ArrayList<>();
        try {
            JSONArray data = new JSONArray(result);
            Gson gson = new Gson();
            for (int i = 0; i < data.length(); i++) {
                CityBean entity = gson.fromJson(data.optJSONObject(i).toString(), CityBean.class);
                detail.add(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
            mHandler.sendEmptyMessage(MSG_LOAD_FAILED);
        }
        return detail;
    }

最后一个是弹出地址选择器的类

 private void ShowPickerView() {// 弹出地址选择器

        OptionsPickerView pvOptions = new OptionsPickerView.Builder(this, new OptionsPickerView.OnOptionsSelectListener() {
            @Override
            public void onOptionsSelect(int options1, int options2, int options3, View v) {
                //返回的分别是三个级别的选中位置
                province = options1Items.get(options1).getPickerViewText();
                city = options2Items.get(options1).get(options2);
//                        + options3Items.get(options1).get(options2).get(options3);
                bank_addr.setText(province+city);
            }
        })

                .setDividerColor(Color.BLACK)
                .setTextColorCenter(Color.BLACK) //设置选中项文字颜色
                .setContentTextSize(20)
                .setOutSideCancelable(false)// default is true
                .build();


        pvOptions.setPicker(options1Items, options2Items);//二级选择器(市区)
//pvOptions.setPicker(options1Items, options2Items, options3Items);//三级选择器
        pvOptions.show();
    }

然后我们在onCreate方法里启动刚才的handle线程

mHandler.sendEmptyMessage(MSG_LOAD_DATA);

大功告成。
city.json的文件忘记给大家了放在下面了,把他粘贴在文本文档里把文本文档的后缀名改成.json就变成json文件了。
city.json

[
  {
    "province": "北京",
    "city_list": [
      "北京"
    ]
  },
  {
    "province": "天津",
    "city_list": [
      "天津"
    ]
  },
  {
    "province": "河北",
    "city_list": [
      "保定",
      "唐山",
      "廊坊",
      "张家口",
      "承德",
      "沧州",
      "石家庄",
      "秦皇岛",
      "衡水",
      "邢台",
      "邯郸"
    ]
  },
  {
    "province": "山西",
    "city_list": [
      "临汾",
      "吕梁",
      "大同",
      "太原",
      "忻州",
      "晋中",
      "晋城",
      "朔州",
      "运城",
      "长治",
      "阳泉"
    ]
  },
  {
    "province": "内蒙古",
    "city_list": [
      "乌兰察布",
      "乌海",
      "兴安",
      "包头",
      "呼伦贝尔",
      "呼和浩特",
      "巴彦淖尔",
      "赤峰",
      "通辽",
      "鄂尔多斯",
      "锡林郭勒",
      "阿拉善"
    ]
  },
  {
    "province": "辽宁",
    "city_list": [
      "丹东",
      "大连",
      "抚顺",
      "朝阳",
      "本溪",
      "沈阳",
      "盘锦",
      "营口",
      "葫芦岛",
      "辽阳",
      "铁岭",
      "锦州",
      "阜新",
      "鞍山"
    ]
  },
  {
    "province": "吉林",
    "city_list": [
      "吉林",
      "四平",
      "延边",
      "松原",
      "白城",
      "白山",
      "辽源",
      "通化",
      "长春"
    ]
  },
  {
    "province": "黑龙江",
    "city_list": [
      "七台河",
      "伊春",
      "佳木斯",
      "双鸭山",
      "哈尔滨",
      "大兴安岭",
      "大庆",
      "牡丹江",
      "绥化",
      "鸡西",
      "鹤岗",
      "黑河",
      "齐齐哈尔"
    ]
  },
  {
    "province": "上海",
    "city_list": [
      "上海"
    ]
  },
  {
    "province": "江苏",
    "city_list": [
      "南京",
      "南通",
      "宿迁",
      "常州",
      "徐州",
      "扬州",
      "无锡",
      "泰州",
      "淮安",
      "盐城",
      "苏州",
      "连云港",
      "镇江"
    ]
  },
  {
    "province": "浙江",
    "city_list": [
      "丽水",
      "台州",
      "嘉兴",
      "宁波",
      "杭州",
      "温州",
      "湖州",
      "绍兴",
      "舟山",
      "衢州",
      "金华"
    ]
  },
  {
    "province": "安徽",
    "city_list": [
      "亳州",
      "六安",
      "合肥",
      "安庆",
      "宣城",
      "宿州",
      "池州",
      "淮北",
      "淮南",
      "滁州",
      "芜湖",
      "蚌埠",
      "铜陵",
      "阜阳",
      "马鞍山",
      "黄山"
    ]
  },
  {
    "province": "福建",
    "city_list": [
      "三明",
      "南平",
      "厦门",
      "宁德",
      "泉州",
      "漳州",
      "福州",
      "莆田",
      "龙岩"
    ]
  },
  {
    "province": "江西",
    "city_list": [
      "上饶",
      "九江",
      "南昌",
      "吉安",
      "宜春",
      "抚州",
      "新余",
      "景德镇",
      "萍乡",
      "赣州",
      "鹰潭"
    ]
  },
  {
    "province": "山东",
    "city_list": [
      "东营",
      "临沂",
      "威海",
      "德州",
      "日照",
      "枣庄",
      "泰安",
      "济南",
      "济宁",
      "淄博",
      "滨州",
      "潍坊",
      "烟台",
      "聊城",
      "莱芜",
      "菏泽",
      "青岛"
    ]
  },
  {
    "province": "河南",
    "city_list": [
      "三门峡",
      "信阳",
      "南阳",
      "周口",
      "商丘",
      "安阳",
      "平顶山",
      "开封",
      "新乡",
      "洛阳",
      "漯河",
      "濮阳",
      "焦作",
      "省直辖",
      "许昌",
      "郑州",
      "驻马店",
      "鹤壁"
    ]
  },
  {
    "province": "湖北",
    "city_list": [
      "十堰",
      "咸宁",
      "孝感",
      "宜昌",
      "恩施",
      "武汉",
      "省直辖",
      "荆州",
      "荆门",
      "襄阳",
      "鄂州",
      "随州",
      "黄冈",
      "黄石"
    ]
  },
  {
    "province": "湖南",
    "city_list": [
      "娄底",
      "岳阳",
      "常德",
      "张家界",
      "怀化",
      "株洲",
      "永州",
      "湘潭",
      "湘西",
      "益阳",
      "衡阳",
      "邵阳",
      "郴州",
      "长沙"
    ]
  },
  {
    "province": "广东",
    "city_list": [
      "东莞",
      "中山",
      "云浮",
      "佛山",
      "广州",
      "惠州",
      "揭阳",
      "梅州",
      "汕头",
      "汕尾",
      "江门",
      "河源",
      "深圳",
      "清远",
      "湛江",
      "潮州",
      "珠海",
      "肇庆",
      "茂名",
      "阳江",
      "韶关"
    ]
  },
  {
    "province": "广西",
    "city_list": [
      "北海",
      "南宁",
      "崇左",
      "来宾",
      "柳州",
      "桂林",
      "梧州",
      "河池",
      "玉林",
      "百色",
      "贵港",
      "贺州",
      "钦州",
      "防城港"
    ]
  },
  {
    "province": "海南",
    "city_list": [
      "三亚",
      "海口",
      "省直辖"
    ]
  },
  {
    "province": "重庆",
    "city_list": [
      "重庆"
    ]
  },
  {
    "province": "四川",
    "city_list": [
      "乐山",
      "内江",
      "凉山",
      "南充",
      "宜宾",
      "巴中",
      "广元",
      "广安",
      "德阳",
      "成都",
      "攀枝花",
      "泸州",
      "甘孜",
      "眉山",
      "绵阳",
      "自贡",
      "资阳",
      "达州",
      "遂宁",
      "阿坝",
      "雅安"
    ]
  },
  {
    "province": "贵州",
    "city_list": [
      "六盘水",
      "安顺",
      "毕节",
      "贵阳",
      "遵义",
      "铜仁",
      "黔东南",
      "黔南",
      "黔西南"
    ]
  },
  {
    "province": "云南",
    "city_list": [
      "临沧",
      "丽江",
      "保山",
      "大理",
      "德宏",
      "怒江",
      "文山",
      "昆明",
      "昭通",
      "普洱",
      "曲靖",
      "楚雄",
      "玉溪",
      "红河",
      "西双版纳",
      "迪庆"
    ]
  },
  {
    "province": "西藏",
    "city_list": [
      "山南",
      "拉萨",
      "日喀则",
      "昌都",
      "林芝",
      "那曲",
      "阿里"
    ]
  },
  {
    "province": "陕西",
    "city_list": [
      "咸阳",
      "商洛",
      "安康",
      "宝鸡",
      "延安",
      "榆林",
      "汉中",
      "渭南",
      "西安",
      "铜川"
    ]
  },
  {
    "province": "甘肃",
    "city_list": [
      "临夏",
      "兰州",
      "嘉峪关",
      "天水",
      "定西",
      "平凉",
      "庆阳",
      "张掖",
      "武威",
      "甘南",
      "白银",
      "酒泉",
      "金昌",
      "陇南"
    ]
  },
  {
    "province": "青海",
    "city_list": [
      "果洛",
      "海东",
      "海北",
      "海南",
      "海西",
      "玉树",
      "西宁",
      "黄南"
    ]
  },
  {
    "province": "宁夏",
    "city_list": [
      "中卫",
      "吴忠",
      "固原",
      "石嘴山",
      "银川"
    ]
  },
  {
    "province": "新疆",
    "city_list": [
      "乌鲁木齐",
      "伊犁",
      "克孜勒苏",
      "克拉玛依",
      "区直辖",
      "博尔塔拉",
      "吐鲁番",
      "和田",
      "哈密",
      "喀什",
      "塔城",
      "巴音郭楞",
      "昌吉",
      "阿克苏",
      "阿勒泰"
    ]
  }
]

你可能感兴趣的:(利用PickerView完成地址选择器(省市二级联动))