基于已有的省份城市数据接口做Android省市联动选择

省份城市选择估计每个入门的 android 码农都做过,而且 Gayhub 上的相关组件琳琅满目搞得大家目不暇接,那么究竟哪个最好用呢,这个我也不知道,只能说大家看项目需求。都不能满足的话只能自己撸一个了,不过我也不是轮子哥,本着站(shen)在巨(shou)人肩上(dang)的原则,这里我用的是 AndroidPicker。

AndroidPicker
https://github.com/gzu-liyujiang/AndroidPicker

然而这个东西可不仅仅是用来做省市地区联动选择用的,还能做文件选择,以及日期选择器、时间选择器、单项选择器、双项选择器、城市地址选择器、车牌号选择器、数字选择器、星座选择器、生肖选择器、颜色选择器、文件选择器、目录选择器等,可自定义顶部及底部界面,可自定义窗口动画 ...

而且估计很多人已经都用过了,用法很简单:

// 创建 AddressPicker 实例
AddressPicker addressPicker = new AddressPicker(当前Activity, 所有省份城市集合);
// 隐藏县、区的选择
addressPicker.setHideCounty(true);
int colorBlack = Color.parseColor("#000000");
// 分割线的颜色
addressPicker.setDividerColor(colorBlack);
addressPicker.setLabelTextColor(colorBlack);
// 取消 文字颜色
addressPicker.setCancelTextColor(Color.parseColor("#FFFFFF"));
// 按下文字时的颜色
addressPicker.setPressedTextColor(Color.parseColor("#FF0030"));
// 确定 文字的颜色
addressPicker.setSubmitTextColor(Color.parseColor("#FF0030"));
// 文字 颜色
addressPicker.setTextColor(colorBlack);
// 对话框标题颜色
addressPicker.setTopBackgroundColor(colorBlack);
addressPicker.setTopLineColor(colorBlack);
// 设置默认省市
addressPicker.setSelectedItem(默认省份, 默认城市);
// 设置事件监听
addressPicker.setOnAddressPickListener(new AddressPicker.OnAddressPickListener() {
    @Override
    public void onAddressPicked(cn.qqtheme.framework.entity.Province province, cn.qqtheme.framework.entity.City city, County county) {
        // TODO
    }
});
// 显示选择对话框
addressPicker.show();

对于城市数据,大家可以在作者的项目 Assets 文件夹中找到 city2.json ,反序列化为 ArrayList<Province> 即可。

https://github.com/gzu-liyujiang/AndroidPicker/blob/master/app/src/main/assets/city2.json

大家以为做项目就这么容易了吗?

Too young,too simple,sometimes naive.

大部分公司开始 app 项目的时候,网站应用已经很完善了,像会员系统牵扯的东西又多,有可能使用的省市数据已经固化到数据库了,并且他们的 id 也不可能有变动,跟业务逻辑耦合了,那么也不可能直接拿 AddressPicker 的数据直接来用了,比如像我的项目中省市数据格式如下:

这和作者的 city2.json 完全长得不是一毛一样,话说作者的这个 json 格式也是 google 地图的格式相同。

那么还有什么办法抢救一下呢,问了接口的少年,人家不愿意再做一层转换 。

那么,自己动手丰衣足食,操起 C# 撸起袖子干了,对项目的 json 实施大转换了。

首先将这个 AddressPicker 的省市区的实体类抄到 C# 中,当然你继续 Java 也可以,我可是把 C# 当 Python 用,写起来也得心应手。

https://github.com/gzu-liyujiang/AndroidPicker/tree/master/library/WheelPicker/src/main/java/cn/qqtheme/framework/entity

对应的 C# 实体类,稍作精简,因为只是做转换。

namespace Java
{
    public class Area
    {
        public String areaId { get; set; }
        public String areaName { get; set; }
    }

    public class City :Area
    {
        public String provinceId { get; set; }
        public List<County> counties { get; set; }
    }

    public class County : Area
    {
        public String cityId { get; set; }
    }

    public class Province : Area
    {
        public List<City> cities { get; set; }
    }
}

接下来是接口中的。

public class Province
{
     public int ProvinceID { get; set; }
     public string ProvinceName { get; set; }
     public List<City> Cities { get; set; }
}

public class City
{
      public int CityID { get; set; }
      public string CityName { get; set; }
}

将接口 json 保存为文件,然后转换为 AddressPicker 所需的 json。

namespace CityBeanConvertor
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputJson = System.IO.File.ReadAllText("GetAllArea.json");
            var provinces = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Province>>(inputJson);
            List<Java.Province> cda = new List<Java.Province>();
            foreach (var item in provinces)
            {
                Java.Province pp = new Java.Province();
                pp.areaId = item.ProvinceID.ToString();
                pp.areaName = item.ProvinceName;

                var cs = item.Cities;
                List<Java.City> ccs = new List<Java.City>();
                if (cs.Count() > 0)
                {
                    foreach (var ct in cs)
                    {
                        Java.City c2 = new Java.City();
                        c2.areaId = ct.CityID.ToString();
                        c2.areaName = ct.CityName;
                        c2.counties = new List<Java.County>();
                        ccs.Add(c2);
                    }
                }
                pp.cities = ccs;
                cda.Add(pp);
            }System.IO.File.WriteAllText("city_igs.json",Newtonsoft.Json.JsonConvert.SerializeObject(cda));
        }
    }
}

最终生成的 city_igs.json 就是符合 AddressPicker 的数据了,至于如果大家项目中也遇到这种问题,完全也可以按照这种办法来了。

理论来说作者的这个组件城市数据包含非常齐全了,完全可以按照字符串是否相等来判断,事实这也可以,但是真实的业务往往比较残忍,比如万一你接口的开发人员打错了一个字?比如你们项目没有覆盖指定的城市的业务所有省份城市列表里没有这个城市。

OK,废话不多说,搞完了就看看实际效果吧,还凑合。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,467评论 1 45
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • 目录 上一章|为了你,我可以放弃一切 第十九章 一醉解千愁 “如风,对不起!我们已经不可能了。因为我已...
    潇湘月明阅读 651评论 1 6
  • 大家好,我是阳光跆拳道蒋老师。今天给大家聊聊“胜不骄败不馁” 古人曾说过:“胜者不骄傲,败者不气馁。”当你取得成功...
    爱读书的愚人阅读 1,543评论 0 1
  • 也許,開始的對立面不是結束 而是永恒的死寂
    憨憨爹阅读 142评论 0 0