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<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");//打開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<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; // 顯示數據 showData(); } } }); }三、顯示數據
RxJava異步讀取數據后就可以顯示了,這里用了三個Spinner來分別顯示省,市,區數據。
顯示的思路大家都清楚,這里不再贅述,代碼如下
/** * 展示數據 */ private void showData() { for (Province province : provinces) { provinceList.add(province.getName()); } // 顯示省份數據 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); // 獲取當前省份對應的城市list 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(); // 刷新城區列表 updateArea(0); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); // 顯示城市數據 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); // 刷新城區列表 updateArea(position); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); // 顯示城區數據 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) { } }); 四、高德地圖獲取當前城市
調用了高德地圖,抽象成了BaseLocationActivity,用的時候只需要繼承自它,然后實現抽象方法LocationResult,即可拿到結果。
模擬器上獲取不到數據,所以沒有顯示,在真機上是可以正常獲取數據的
代碼地址:下載地址。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。
新聞熱點
疑難解答