Android省市区选择三级联动效果,一个不大不小的功能,就算你做过,但是没有相关的代码直接写,也要花掉你至少半天时间。

下面我写出我的实现过程(思路绝对清晰)。

先上效果图


一,准备数据

我是用的本地的json数据(走网络的话太慢,每次都要请求),放在asserts中。格式如下:

[{    "name": "河北省",    "city": [      {        "name": "石家庄市",        "area": [          "长安区",          "桥东区",          "桥西区",          "新华区",          "郊  区",          "井陉矿区",          "井陉县",          "正定县",          "栾城县",          "行唐县",          "灵寿县",          "高邑县",          "深泽县",          "赞皇县",          "无极县",          "平山县",          "元氏县",          "赵  县",          "辛集市",          "藁",          "晋州市",          "新乐市",          "鹿泉市"        ]      },......]
二,解析数据

首先根据json生成Province对象

然后通过getAssets().open("citylist.json");获取文件输入流,接着转成字节,最终获取字符串。

然后用Gson解析字符串得到Province的List对象。由于读文件是IO操作,这里我用了RxJava,代码如下:

/**     * 从assert文件夹中获取json数据     */    private void initJsonData() {        Observable.create(new ObservableOnSubscribe>() {            @Override            public void subscribe(ObservableEmitter> emitter) throws Exception {                List provinces = new ArrayList<>();                try {                    StringBuffer sb = new StringBuffer();                    InputStream is = getAssets().open("citylist.json");//打开json数据                    byte[] by = new byte[is.available()];//转字节                    int len = -1;                    while ((len = is.read(by)) != -1) {                        sb.append(new String(by, 0, len, "utf8"));//根据字节长度设置编码                    }                    is.close();// 关闭流                    // 通过Gson将字符串转成对象list                    Gson gson = new Gson();                    provinces = gson.fromJson(sb.toString(), new TypeToken>() {                    }.getType());                } catch (Exception e) {                    e.printStackTrace();                } finally {                    emitter.onNext(provinces);                }            }        }).subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Consumer>() {                    @Override                    public void accept(List provinces) throws Exception {                        if (provinces != null && provinces.size() > 0) {                            RegionSelectActivity.this.provinces = provinces;                            // 显示数据                            showData();                        }                    }                });    }
三,显示数据

RxJava异步读取数据后就可以显示了,这里用了三个Spinner来分别显示省,市,区数据。

显示的思路大家都清楚,这里不再赘述,代码如下

/**     * 展示数据     */    private void showData() {        for (Province province : provinces) {            provinceList.add(province.getName());        }        // 显示省份数据        spProvince.setAdapter(new ArrayAdapter(this, android.R.layout.simple_spinner_item, provinceList));        spProvince.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {            @Override            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {                provincePosition = position;                provinceName = provinceList.get(position);                // 获取当前省份对应的城市list                cityList.clear();                List cityBeans = provinces.get(position).getCity();                for (Province.CityBean city : cityBeans) {                    cityList.add(city.getName());                }                // 刷新城市列表                spCity.setSelection(0);                cityName = cityList.get(0);                cityAdapter.notifyDataSetChanged();                // 刷新城区列表                updateArea(0);            }            @Override            public void onNothingSelected(AdapterView<?> parent) {            }        });        // 显示城市数据        spCity.setAdapter(cityAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, cityList));        spCity.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {            @Override            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {                cityPosition = position;                cityName = cityList.get(position);                // 刷新城区列表                updateArea(position);            }            @Override            public void onNothingSelected(AdapterView<?> parent) {            }        });        // 显示城区数据        spArea.setAdapter(areaAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, areaList));        spArea.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {            @Override            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {                areaName = areaList.get(position);            }            @Override            public void onNothingSelected(AdapterView<?> parent) {            }        });
四,高德地图获取当前城市

调用了高德地图,抽象成了BaseLocationActivity,用的时候只需要继承自它,然后实现抽象方法LocationResult,即可拿到结果。

模拟器上获取不到数据,所以没有显示,在真机上是可以正常获取数据的

代码地址:







更多相关文章

  1. smem在Android中的使用
  2. [原]Android应用程序绑定服务(bindService)的过程源代码分析
  3. android studio中如何导入github项目
  4. Android之TelephonyManager类的方法详解
  5. Android(安卓)NDK入门
  6. Android基础总结之八:ContentProvider
  7. 安卓实现扫一扫识别数字
  8. android 使用服务读取串口数据实例
  9. Android之——自定义下拉菜单的实现

随机推荐

  1. Android实现静默安装与卸载
  2. 将Android工程做成jar包和资源文件
  3. 【Android】Android(安卓)手机忘记锁屏密
  4. Android(安卓)Zip文件解压缩代码
  5. android 线程间的通信
  6. 如何使用Android(安卓)SDK开发Android应
  7. Android应用程序注册广播接收器(registerR
  8. Android(安卓)adb配置环境变量
  9. Android(安卓)多个APK共享数据(Shared Us
  10. Android主题换肤 无缝切换