1. 程式人生 > >Android——實現全國省市區地區選擇

Android——實現全國省市區地區選擇

android的地區選擇,這個實在是太常見了,比如淘寶下單後的填寫地址裡面也有地區選擇功能,微信裡面也有收貨地址,再者一些app的定位選擇等等,

實現起來也並不是很困難的事,網上也有全國省市區的介面api,調介面的方式更簡單,只不過網路請求速度慢了些,寫了個demo,在本地的省市區json檔案集合實現全國三級地區選擇,這裡我也主要貼下主要的程式碼,後面把專案的下載地址分享出來。

專案結構:
這裡寫圖片描述

主要程式碼,ShowRegionActivity類:

package com.lai.regionselection;

import android.app.Activity;
import
android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.Window; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.Spinner; import org.json.JSONArray; import
org.json.JSONException; import org.json.JSONObject; import java.io.InputStream; import java.util.HashMap; import java.util.Map; /** * Created by laiyingtang on 2016/8/3. */ public class ShowRegionActivity extends Activity { private Spinner spinner_sheng;//省 private Spinner spinner_shi;//市 private
Spinner spinner_qu;//區 private EditText et_detailAddress;//輸入詳細地址 private Button btn_confirm;//確認按鈕 private int resultCode = 102;//返回碼 //全域性的jsonObject private JSONObject jsonObject;//把全國的省市區的資訊以json的格式儲存,解析完成後賦值為null private String[] allProv;//所有的省 private ArrayAdapter<String> provinceAdapter;//省份資料介面卡 private ArrayAdapter<String> cityAdapter;//城市資料介面卡 private ArrayAdapter<String> areaAdapter;//區縣資料介面卡 private String[] allSpinList;//在spinner中選出來的地址,後面需要用空格隔開省市區 private String address;//用來接收intent的引數 private String allAddress;//用來接收intent引數 private String provinceName;//省的名字 private String areaName;//區的名字 private Boolean isFirstLoad = true;//判斷是不是最近進入對話方塊 private Boolean ifSetFirstAddress = true;//判斷是否已經設定了,初始的詳細地址 //省市區的集合 private Map<String, String[]> cityMap = new HashMap<String, String[]>();//key:省p---value:市n value是一個集合 private Map<String, String[]> areaMap = new HashMap<String, String[]>();//key:市n---value:區s 區也是一個集合 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);//設定視窗不顯示標題 setContentView(R.layout.activity_region); initJsonData();//初始化json資料 initDatas();//初始化省市區資料 initView();//初始化控制元件 initClick();//初始化點選 setSpinnerData();//為spinner設定值 } /** * spinner設定值(預設設定值) */ private void setSpinnerData() { int selectPosition = 0;//有資料傳入時 address = getIntent().getStringExtra("address"); allAddress = getIntent().getStringExtra("allAddress"); if (address != null && !address.equals("") && allAddress != null && !allAddress.equals("")) { allSpinList = address.split(" ");//用空格隔開allSpinList地址 } /** * 設定省市區的介面卡,進行動態設定 */ provinceAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);//系統預設的 for (int i = 0; i < allProv.length; i++) { //給spinner省賦值,設定預設值 if (address != null && !address.equals("") && allAddress != null && !allAddress.equals("")&& allSpinList.length > 0 && allSpinList[0].equals(allProv[i])) { selectPosition = i; } provinceAdapter.add(allProv[i]);//新增每一個省 } provinceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);//按下的效果 spinner_sheng.setAdapter(provinceAdapter); spinner_sheng.setSelection(selectPosition);//設定選中的省,預設 //市 cityAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item); cityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner_shi.setAdapter(cityAdapter); //區縣 areaAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item); areaAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner_qu.setAdapter(areaAdapter); setListener();//設定spinner的點選監聽 } //設定spinner的點選監聽 private void setListener() { //省 spinner_sheng.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { provinceName = parent.getSelectedItem() + "";//獲取點選列表spinner item的省名字 if (isFirstLoad) { // 判斷是否省市區都存在 if (address != null && !address.equals("") && allAddress != null && !allAddress.equals("")&& allSpinList.length > 1 && allSpinList.length < 3) { updateCityAndArea(provinceName, allSpinList[1], null);//更新市和區 } else if (address != null && !address.equals("") && allAddress != null && !allAddress.equals("") && allSpinList.length >= 3) { //存在省市區 //去更新 updateCityAndArea(provinceName, allSpinList[1], allSpinList[2]); } else { updateCityAndArea(provinceName, null, null); } } else { updateCityAndArea(provinceName, null, null); } } @Override public void onNothingSelected(AdapterView<?> parent) { } }); //市 spinner_shi.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { if (!isFirstLoad) { //更新區 updateArea(parent.getSelectedItem() + "", null); } else { if (address != null && !address.equals("") && allAddress != null && !allAddress.equals("") && allSpinList.length == 4) { et_detailAddress.setText(allSpinList[3]);//沒有進入區的對話方塊, } } isFirstLoad = false; } @Override public void onNothingSelected(AdapterView<?> parent) { } }); //區 spinner_qu.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //直接獲取區的名字 areaName = parent.getSelectedItem() + ""; } @Override public void onNothingSelected(AdapterView<?> parent) { } }); } /** * 根據當前的省,更新市和區的資訊 */ private void updateCityAndArea(Object object, Object city, Object area) { int selectPosition = 0;//有資料時,進行匹配城市,預設選中 String[] cities = cityMap.get(object); cityAdapter.clear();//清空adapter的資料 for (int i = 0; i < cities.length; i++) { if (city != null && city.toString().equals(cities[i])) {//判斷傳入的市在集合中匹配 selectPosition = i; } cityAdapter.add(cities[i]);//將這個列表“市”新增到adapter中 } cityAdapter.notifyDataSetChanged();//重新整理 if (city == null) { updateArea(cities[0], null);//更新區,沒有市則預設第一個給它 } else { spinner_shi.setSelection(selectPosition); updateArea(city, area);//穿入的區去集合中匹配 } } //根據當前的市,更新區的資訊 private void updateArea(Object object, Object myArea) { boolean isArea = false;//判斷第三個地址是地區還是詳細地址 int selectPosition = 0;//當有資料時,進行匹配地區,預設選中 String[] area = areaMap.get(object); areaAdapter.clear();//清空 if (area != null) { for (int i = 0; i < area.length; i++) { if (myArea != null && myArea.toString().equals(area[i])) {//去集合中匹配 selectPosition = i; isArea = true;//地區 } areaAdapter.add(area[i]);//填入到這個列表 } areaAdapter.notifyDataSetChanged();//重新整理 spinner_qu.setSelection(selectPosition);//預設選中 } //第三個地址是詳細地址,並且是第一次設定edtext值,正好,地址的長度為3的時候,設定詳細地址 if (!isArea && ifSetFirstAddress && address != null && !address.equals("") && allAddress != null && !allAddress.equals("") && allSpinList.length == 3) { et_detailAddress.setText(allSpinList[2]); ifSetFirstAddress = false; } } //初始化省市區資料 private void initDatas() { try { JSONArray jsonArray = jsonObject.getJSONArray("citylist");//獲取整個json資料 allProv = new String[jsonArray.length()];//封裝資料 for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonP = jsonArray.getJSONObject(i);//jsonArray轉jsonObject String provStr = jsonP.getString("p");//獲取所有的省 allProv[i] = provStr;//封裝所有的省 JSONArray jsonCity = null; try { jsonCity = jsonP.getJSONArray("c");//在所有的省中取出所有的市,轉jsonArray } catch (Exception e) { continue; } //所有的市 String[] allCity = new String[jsonCity.length()];//所有市的長度 for (int c = 0; c < jsonCity.length(); c++) { JSONObject jsonCy = jsonCity.getJSONObject(c);//轉jsonObject String cityStr = jsonCy.getString("n");//取出所有的市 allCity[c] = cityStr;//封裝市集合 JSONArray jsonArea = null; try { jsonArea = jsonCy.getJSONArray("a");//在從所有的市裡面取出所有的區,轉jsonArray } catch (Exception e) { continue; } String[] allArea = new String[jsonArea.length()];//所有的區 for (int a = 0; a < jsonArea.length(); a++) { JSONObject jsonAa = jsonArea.getJSONObject(a); String areaStr = jsonAa.getString("s");//獲取所有的區 allArea[a] = areaStr;//封裝起來 } areaMap.put(cityStr, allArea);//某個市取出所有的區集合 } cityMap.put(provStr, allCity);//某個省取出所有的市, } } catch (JSONException e) { e.printStackTrace(); } jsonObject = null;//清空所有的資料 } /** * 從assert資料夾中獲取json資料 */ private void initJsonData() { try { StringBuffer sb = new StringBuffer(); InputStream is = getAssets().open("city.json");//開啟json資料 byte[] by = new byte[is.available()];//轉位元組 int len = -1; while ((len = is.read(by)) != -1) { sb.append(new String(by, 0, len, "gb2312"));//根據位元組長度設定編碼 } is.close();//關閉流 jsonObject = new JSONObject(sb.toString());//為json賦值 } catch (Exception e) { e.printStackTrace(); } } //初始化點選 private void initClick() { btn_confirm.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //把值返回給MainActivity Intent intent = new Intent(); areaName = spinner_qu.getSelectedItem() == null ? "" : spinner_qu.getSelectedItem().toString(); intent.putExtra("address", spinner_sheng.getSelectedItem() + " " + spinner_shi.getSelectedItem() + " " + areaName); intent.putExtra("allAddress", et_detailAddress.getText().toString()); setResult(resultCode, intent); finish(); } }); } //初始化控制元件 private void initView() { spinner_sheng = (Spinner) findViewById(R.id.spinner_sheng); spinner_shi = (Spinner) findViewById(R.id.spinner_shi); spinner_qu = (Spinner) findViewById(R.id.spinner_qu); et_detailAddress = (EditText) findViewById(R.id.et_detailAddress); btn_confirm = (Button) findViewById(R.id.btn_confirm); } }

效果如下:
這裡寫圖片描述

註釋也寫了,大家慢慢消化吧!邏輯很清晰,只是程式碼量多了些。如果用Rxjava或許容易懂些,最後我把專案地址附上

下載地址