android 省市县联动菜单,最好用的Android省市区三级联动选择效果

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,即可拿到结果。

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

代码地址:下载地址。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值