最好用的Android省市區(qū)三級(jí)聯(lián)動(dòng)選擇效果
Android省市區(qū)選擇三級(jí)聯(lián)動(dòng)效果,一個(gè)不大不小的功能,就算你做過(guò),但是沒(méi)有相關(guān)的代碼直接寫(xiě),也要花掉你至少半天時(shí)間。
下面我寫(xiě)出我的實(shí)現(xiàn)過(guò)程(思路絕對(duì)清晰)。
先上效果圖

一、準(zhǔn)備數(shù)據(jù)
我是用的本地的json數(shù)據(jù)(走網(wǎng)絡(luò)的話(huà)太慢,每次都要請(qǐng)求),放在asserts中。格式如下:
[{
"name": "河北省",
"city": [
{
"name": "石家莊市",
"area": [
"長(zhǎng)安區(qū)",
"橋東區(qū)",
"橋西區(qū)",
"新華區(qū)",
"郊 區(qū)",
"井陘礦區(qū)",
"井陘縣",
"正定縣",
"欒城縣",
"行唐縣",
"靈壽縣",
"高邑縣",
"深澤縣",
"贊皇縣",
"無(wú)極縣",
"平山縣",
"元氏縣",
"趙 縣",
"辛集市",
"藁",
"晉州市",
"新樂(lè)市",
"鹿泉市"
]
},......]
二、解析數(shù)據(jù)
首先根據(jù)json生成Province對(duì)象
然后通過(guò)getAssets().open("citylist.json");獲取文件輸入流,接著轉(zhuǎn)成字節(jié),最終獲取字符串。
然后用Gson解析字符串得到Province的List對(duì)象。由于讀文件是IO操作,這里我用了RxJava,代碼如下:
/**
* 從assert文件夾中獲取json數(shù)據(jù)
*/
private void initJsonData() {
Observable.create(new ObservableOnSubscribe<List<Province>>() {
@Override
public void subscribe(ObservableEmitter<List<Province>> emitter) throws Exception {
List<Province> provinces = new ArrayList<>();
try {
StringBuffer sb = new StringBuffer();
InputStream is = getAssets().open("citylist.json");//打開(kāi)json數(shù)據(jù)
byte[] by = new byte[is.available()];//轉(zhuǎn)字節(jié)
int len = -1;
while ((len = is.read(by)) != -1) {
sb.append(new String(by, 0, len, "utf8"));//根據(jù)字節(jié)長(zhǎng)度設(shè)置編碼
}
is.close();// 關(guān)閉流
// 通過(guò)Gson將字符串轉(zhuǎn)成對(duì)象list
Gson gson = new Gson();
provinces = gson.fromJson(sb.toString(), new TypeToken<List<Province>>() {
}.getType());
} catch (Exception e) {
e.printStackTrace();
} finally {
emitter.onNext(provinces);
}
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<Province>>() {
@Override
public void accept(List<Province> provinces) throws Exception {
if (provinces != null && provinces.size() > 0) {
RegionSelectActivity.this.provinces = provinces;
// 顯示數(shù)據(jù)
showData();
}
}
});
}
三、顯示數(shù)據(jù)
RxJava異步讀取數(shù)據(jù)后就可以顯示了,這里用了三個(gè)Spinner來(lái)分別顯示省,市,區(qū)數(shù)據(jù)。
顯示的思路大家都清楚,這里不再贅述,代碼如下
/**
* 展示數(shù)據(jù)
*/
private void showData() {
for (Province province : provinces) {
provinceList.add(province.getName());
}
// 顯示省份數(shù)據(jù)
spProvince.setAdapter(new ArrayAdapter<String>(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);
// 獲取當(dāng)前省份對(duì)應(yīng)的城市l(wèi)ist
cityList.clear();
List<Province.CityBean> cityBeans = provinces.get(position).getCity();
for (Province.CityBean city : cityBeans) {
cityList.add(city.getName());
}
// 刷新城市列表
spCity.setSelection(0);
cityName = cityList.get(0);
cityAdapter.notifyDataSetChanged();
// 刷新城區(qū)列表
updateArea(0);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
// 顯示城市數(shù)據(jù)
spCity.setAdapter(cityAdapter = new ArrayAdapter<String>(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);
// 刷新城區(qū)列表
updateArea(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
// 顯示城區(qū)數(shù)據(jù)
spArea.setAdapter(areaAdapter = new ArrayAdapter<String>(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) {
}
});
四、高德地圖獲取當(dāng)前城市
調(diào)用了高德地圖,抽象成了BaseLocationActivity,用的時(shí)候只需要繼承自它,然后實(shí)現(xiàn)抽象方法LocationResult,即可拿到結(jié)果。
模擬器上獲取不到數(shù)據(jù),所以沒(méi)有顯示,在真機(jī)上是可以正常獲取數(shù)據(jù)的
代碼地址:下載地址。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android PickerView實(shí)現(xiàn)三級(jí)聯(lián)動(dòng)效果
- Android實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)
- Android日期選擇器實(shí)現(xiàn)年月日三級(jí)聯(lián)動(dòng)
- Android中使用開(kāi)源框架Citypickerview實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)選擇
- Android自定義WheelView地區(qū)選擇三級(jí)聯(lián)動(dòng)
- Android省市區(qū)三級(jí)聯(lián)動(dòng)控件使用方法實(shí)例講解
- android-wheel控件實(shí)現(xiàn)三級(jí)聯(lián)動(dòng)效果
- Android使用android-wheel實(shí)現(xiàn)省市縣三級(jí)聯(lián)動(dòng)
- Android實(shí)現(xiàn)聯(lián)動(dòng)下拉框 下拉列表spinner的實(shí)例代碼
- Android實(shí)現(xiàn)城市選擇三級(jí)聯(lián)動(dòng)
相關(guān)文章
Android中EditText 設(shè)置 imeOptions 無(wú)效問(wèn)題的解決方法
有時(shí)候我們需要在EditText 輸出完之后 需要在鍵盤(pán)出現(xiàn) 右下角變成“Go”或“前往 搜索時(shí);通常我們需要設(shè)置Android:imeOptions屬性,但是今天我發(fā)現(xiàn)設(shè)置了無(wú)效,下面給大家分享下解決方案2016-12-12
Android性能優(yōu)化之RecyclerView分頁(yè)加載組件功能詳解
這篇文章主要為大家介紹了Android性能優(yōu)化之RecyclerView分頁(yè)加載組件功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Android采用GET方法進(jìn)行網(wǎng)絡(luò)傳值
這篇文章主要為大家詳細(xì)介紹了Android采用GET方法進(jìn)行網(wǎng)絡(luò)傳值的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
android viewpager實(shí)現(xiàn)豎直滑動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了android viewpager實(shí)現(xiàn)豎直滑動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Android中協(xié)調(diào)滾動(dòng)布局的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android中協(xié)調(diào)滾動(dòng)常用的布局實(shí)現(xiàn),類(lèi)似這樣的協(xié)調(diào)滾動(dòng)布局,當(dāng)?shù)撞苛斜砘瑒?dòng)的時(shí)候,頂部的布局做響應(yīng)的動(dòng)作,我們都可以通過(guò)?AppBarLayout?和?MotionLayout?來(lái)實(shí)現(xiàn),本文通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友參考下吧2022-06-06
移動(dòng)端android上line-height不居中的問(wèn)題的解決
現(xiàn)在越來(lái)越多的移動(dòng)界面使用rem適配,最近發(fā)現(xiàn)了移動(dòng)端android上line-height不居中的問(wèn)題,今日就來(lái)介紹一下解決的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-03-03
Android Compose 屬性動(dòng)畫(huà)使用探索詳解
這篇文章主要為大家介紹了Android Compose 屬性動(dòng)畫(huà)使用探索詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Android使用CoordinatorLayout實(shí)現(xiàn)底部彈出菜單
這篇文章主要為大家詳細(xì)介紹了Android使用CoordinatorLayout實(shí)現(xiàn)底部彈出菜單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11

