1. 程式人生 > >Android省市縣三級聯動 真實專案抽出 呼叫只需3行程式碼

Android省市縣三級聯動 真實專案抽出 呼叫只需3行程式碼

  • 專案原始碼:包含日期、省市縣兩種選擇器[資源積分:0分] ,APK安裝包下載,沒有CSDN賬戶的的點此下載原始碼
  • fastjson自己複製部落格裡原始碼的小夥伴,注意匯入fastjson框架哦!阿里巴巴出品的最快json解析框架
  • 日期選擇器:效果圖中的選擇年月日的日期選擇器
  • 任何問題,歡迎評論;原始碼下載不成功的留下郵箱;文章我還在維護,持續優化,有問題的小夥伴積極評論哈。

先上效果圖: 樣式可以修改xml檔案


  • 省市縣三級聯動,選地址經常用到
  • 原生NumberPicker控制元件實現滑動,json資料解析使用fastjson框架
  • 使用簡單:傳入一個String[]陣列,設定選擇器的預設值,點選確認按鈕,回撥介面返回String[]陣列,為重新選擇的省市縣
  • 隨意修改:效果圖中字型顏色佈局等都可以修改,以保證與你的專案風格統一

把我原始碼裡寫好的java檔案和xml檔案拷到你的專案中,呼叫就這麼簡單:

  1. ChooseCityUtil cityUtil = new ChooseCityUtil();  
  2.        String[] oldCityArray = {"廣東","深圳","福田"};  
  3.        cityUtil.createDialog(this, oldCityArray, new ChooseCityInterface() {  
  4.            @Override
  5.            publicvoid sure(String[] newCityArray) {  
  6.                //oldCityArray為傳入的預設值 newCityArray為返回的結果
  7.                tvCity.setText(newCityArray[0] + "-" + newCityArray[1] + "-" + newCityArray[2]);  
  8.            }  
  9.        });  

-------------------------------------------------------- 我是分割線 --------------------------------------------------------

接下來看是如何實現的

佈局檔案activity_main.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:tools="http://schemas.android.com/tools"
  4.     android:layout_width="match_parent"
  5.     android:layout_height="match_parent"
  6.     android:fitsSystemWindows="true"
  7.     android:orientation="vertical"
  8.     tools:context=".MainActivity">  
  9.     <TextView  
  10.         android:layout_width="match_parent"
  11.         android:layout_height="56dp"
  12.         android:background="@color/mainColor"
  13.         android:gravity="center"
  14.         android:text="選擇器 Picker"
  15.         android:textColor="@color/white"
  16.         android:textSize="20sp" />  
  17.     <RelativeLayout  
  18.         android:layout_width="match_parent"
  19.         android:layout_height="50dp"
  20.         android:orientation="horizontal">  
  21.         <TextView  
  22.             android:layout_width="wrap_content"
  23.             android:layout_height="match_parent"
  24.             android:gravity="center"
  25.             android:text="城市設定:"
  26.             android:textColor="#656565"
  27.             android:textSize="18sp" />  
  28.         <TextView  
  29.             android:id="@+id/tvCity"
  30.             android:layout_width="wrap_content"
  31.             android:layout_height="match_parent"
  32.             android:layout_alignParentRight="true"
  33.             android:clickable="true"
  34.             android:gravity="center"
  35.             android:onClick="chooseCityDialog"
  36.             android:text="廣東-深圳-福田"
  37.             android:textColor="#656565"
  38.             android:textSize="18sp" />  
  39.     </RelativeLayout>  
  40.     <View  
  41.         android:layout_width="match_parent"
  42.         android:layout_height="0.1dp"
  43.         android:background="@color/gray" />  
  44. </LinearLayout>  


對話方塊佈局檔案 dialog_choose_city.xml:
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     android:background="#00000000"
  6.     android:gravity="center"
  7.     android:orientation="vertical">  
  8.     <LinearLayout  
  9.         android:layout_width="260dp"
  10.         android:layout_height="wrap_content"
  11.         android:orientation="vertical"
  12.         android:background="#FFF">  
  13.         <LinearLayout  
  14.             android:layout_width="match_parent"
  15.             android:layout_height="wrap_content"
  16.             android:orientation="horizontal">  
  17.             <NumberPicker  
  18.                 android:id="@+id/npProvince"
  19.                 android:layout_width="0dp"
  20.                 android:layout_weight="1"
  21.                 android:layout_height="wrap_content"/>  
  22.             <TextView  
  23.                 android:layout_width="wrap_content"
  24.                 android:layout_marginLeft="3dp"
  25.                 android:layout_marginRight="3dp"
  26.                 android:layout_height="match_parent"
  27.                 android:gravity="center"
  28.                 android:text="省"
  29.                 android:textColor="#656565"
  30.                 android:textSize="18sp" />  
  31.             <NumberPicker  
  32.                 android:id="@+id/npCity"
  33.                 android:layout_width="0dp"
  34.                 android:layout_weight="1"
  35.                 android:layout_height="wrap_content" />  
  36.             <TextView  
  37.                 android:layout_width="wrap_content"
  38.                 android:layout_marginLeft="3dp"
  39.                 android:layout_marginRight="3dp"
  40.                 android:layout_height="match_parent"
  41.                 android:gravity="center"
  42.                 android:text="市"
  43.                 android:textColor="#656565"
  44.                 android:textSize="18sp" />  
  45.             <NumberPicker  
  46.                 android:id="@+id/npCounty"
  47.                 android:layout_width="0dp"
  48.                 android:layout_weight="1"
  49.                 android:layout_height="wrap_content" />  
  50.             <TextView  
  51.                 android:layout_width="wrap_content"
  52.                 android:layout_height="match_parent"
  53.                 android:gravity="center"
  54.                 android:text=""
  55.                 android:textColor="#656565"
  56.                 android:textSize="18sp" />  
  57.         </LinearLayout>  
  58.         <View  
  59.             android:layout_width="match_parent"
  60.             android:layout_height="0.1dp"
  61.             android:background="#EEEEEE"/>  
  62.         <LinearLayout  
  63.             android:layout_width="match_parent"
  64.             android:layout_height="50dp"
  65.             android:orientation="horizontal">  
  66.             <TextView  
  67.                 android:id="@+id/tvCancel"
  68.                 android:layout_width="0dp"
  69.                 android:layout_height="match_parent"
  70.                 android:layout_weight="1"
  71.                 android:gravity="center"
  72.                 android:text="取消"
  73.                 android:textColor="#656565"
  74.                 android:textSize="18sp" />  
  75.             <TextView  
  76.                 android:id="@+id/tvSure"
  77.                 android:layout_width="0dp"
  78.                 android:layout_height="match_parent"
  79.                 android:layout_weight="1"
  80.                 android:gravity="center"
  81.                 android:text="確定"
  82.                 android:textColor="#656565"
  83.                 android:textSize="18sp" />  
  84.         </LinearLayout>  
  85.     </LinearLayout>  
  86. </LinearLayout>  

介面類ChooseCityInterface.java

  1. publicinterface ChooseCityInterface {  
  2.     publicvoid sure(String[] newCityArray);  
  3. }  

json對應實體類CityBean.java

  1. publicclass CityBean {  
  2.     private String note;  
  3.     private List<Data> data;  
  4.     public String getNote() {  
  5.         return note;  
  6.     }  
  7.     publicvoid setNote(String note) {  
  8.         this.note = note;  
  9.     }  
  10.     public List<Data> getData() {  
  11.         return data;  
  12.     }  
  13.     publicvoid setData(List<Data> data) {  
  14.         this.data = data;  
  15.     }  
  16.     publicstaticclass Data {  
  17.         private String name;  
  18.         private List<City> city;  
  19.         public String getName() {  
  20.             return name;  
  21.         }  
  22.         publicvoid setName(String name) {  
  23.             this.name = name;  
  24.         }  
  25.         public List<City> getCity() {  
  26.             return city;  
  27.         }  
  28.         publicvoid setCity(List<City> city) {  
  29.             this.city = city;  
  30.         }  
  31.         publicstaticclass City {  
  32.             private String name;  
  33.             private List<String> county;  
  34.             public String getName() {  
  35.                 return name;  
  36.             }  
  37.             publicvoid setName(String name) {  
  38.                 this.name = name;  
  39.             }  
  40.             public List<String> getCounty() {  
  41.                 return county;  
  42.             }  
  43.             publicvoid setCounty(List<String> county) {  
  44.                 this.county = county;  
  45.             }  
  46.         }  
  47.     }  
  48. }  
選擇地址對話方塊工具類 ChooseCityUtil.java
  1. publicclass ChooseCityUtil implements View.OnClickListener, NumberPicker.OnValueChangeListener {  
  2.     Context context;  
  3.     AlertDialog dialog;  
  4.     ChooseCityInterface cityInterface;  
  5.     NumberPicker npProvince, npCity, npCounty;  
  6.     TextView tvCancel, tvSure;  
  7.     String[] newCityArray = new String[3];  
  8.     CityBean bean;  
  9.     publicvoid createDialog(Context context, String[] oldCityArray, ChooseCityInterface cityInterface) {  
  10.         this.context = context;  
  11.         this.cityInterface = cityInterface;  
  12.         bean = JSON.parseObject(CityData.getJson(), CityBean.class);  
  13.         newCityArray[0] = oldCityArray[0];  
  14.         newCityArray[1] = oldCityArray[1];  
  15.         newCityArray[2] = oldCityArray[2];  
  16.         dialog = new AlertDialog.Builder(context).create();  
  17.         dialog.show();  
  18.         Window window = dialog.getWindow();  
  19.         window.setContentView(R.layout.dialog_choose_city);  
  20.         //初始化控制元件
  21.         tvCancel = (TextView) window.findViewById(R.id.tvCancel);  
  22.         tvSure = (TextView) window.findViewById(R.id.tvSure);  
  23.         tvCancel.setOnClickListener(this);  
  24.         tvSure.setOnClickListener(this);  
  25.         npProvince = (NumberPicker) window.findViewById(R.id.npProvince);  
  26.         npCity = (NumberPicker) window.findViewById(R.id.npCity);  
  27.         npCounty = (NumberPicker) window.findViewById(R.id.npCounty);  
  28.         setNomal();  
  29.         //省:設定選擇器最小值、最大值、初始值
  30.         String[] provinceArray = new String[bean.getData().size()];//初始化省陣列
  31.         for (int i = 0; i < provinceArray.length; i++) {//省陣列填充資料
  32.             provinceArray[i] = bean.getData().get(i).getName();  
  33.         }  
  34.         npProvince.setDisplayedValues(provinceArray);//設定選擇器資料、預設值
  35.         npProvince.setMinValue(0);  
  36.         npProvince.setMaxValue(provinceArray.length - 1);  
  37.         for (int i = 0; i < provinceArray.length; i++) {  
  38.             if (provinceArray[i].equals(newCityArray[0])) {  
  39.                 npProvince.setValue(i);  
  40.                 changeCity(i);//聯動市資料
  41.             }  
  42.         }  
  43.     }  
  44.     //根據省,聯動市資料
  45.     privatevoid changeCity(int provinceTag) {  
  46.         List<CityBean.Data.City> cityList = bean.getData().get(provinceTag).getCity();  
  47.         String[] cityArray = new String[cityList.size()];  
  48.         for (int i = 0; i < cityArray.length; i++) {  
  49.             cityArray[i] = cityList.get(i).getName();  
  50.         }  
  51.         try {  
  52.             npCity.setMinValue(0);  
  53.             npCity.setMaxValue(cityArray.length - 1);  
  54.             npCity.setWrapSelectorWheel(false);  
  55.             npCity.setDisplayedValues(cityArray);//設定選擇器資料、預設值
  56.         } catch (Exception e) {  
  57.             npCity.setDisplayedValues(cityArray);//設定選擇器資料、預設值
  58.             npCity.setMinValue(0);  
  59.             npCity.setMaxValue(cityArray.length - 1);  
  60.             npCity.setWrapSelectorWheel(false);  
  61.         }  
  62.         for (int i = 0; i < cityArray.length; i++) {  
  63.             if (cityArray[i].equals(newCityArray[1])) {  
  64.                 npCity.setValue(i);  
  65.                 changeCounty(provinceTag, i);//聯動縣資料
  66.                 return;  
  67.             }  
  68.         }  
  69.         npCity.setValue(0);  
  70.         changeCounty(provinceTag, npCity.getValue());//聯動縣資料
  71.     }  
  72.     //根據市,聯動縣資料
  73.     privatevoid changeCounty(int provinceTag, int cityTag) {  
  74.         List<String> countyList = bean.getData().get(provinceTag).getCity().get(cityTag).getCounty();  
  75.         String[] countyArray = new String[countyList.size()];  
  76.         for (int i = 0; i < countyArray.length; i++) {  
  77.             countyArray[i] = countyList.get(i).toString();  
  78.         }  
  79.         try {  
  80.             npCounty.setMinValue(0);  
  81.             npCounty.setMaxValue(countyArray.length - 1);  
  82.             npCounty.setWrapSelectorWheel(false);  
  83.             npCounty.setDisplayedValues(countyArray);//設定選擇器資料、預設值
  84.         } catch (Exception e) {  
  85.             npCounty.setDisplayedValues(countyArray);//設定選擇器資料、預設值
  86.             npCounty.setMinValue(0);  
  87.             npCounty.setMaxValue(countyArray.length - 1);  
  88.             npCounty.setWrapSelectorWheel(false);  
  89.         }  
  90.         for (int i = 0; i < countyArray.length; i++) {  
  91.             if (countyArray[i].equals(newCityArray[2])) {  
  92.                 npCounty.setValue(i);  
  93.                 return;  
  94.             }  
  95.         }  
  96.         npCounty.setValue(0);  
  97.     }  
  98.     //設定NumberPicker的分割線透明、字型顏色、設定監聽
  99.     privatevoid setNomal() {  
  100.         //設定監聽
  101.         npProvince.setOnValueChangedListener(this);  
  102.         npCity.setOnValueChangedListener(this);  
  103.         npCounty.setOnValueChangedListener(this);  
  104.         //去除分割線
  105.         setNumberPickerDividerColor(npProvince);  
  106.         setNumberPickerDividerColor(npCity);  
  107.         setNumberPickerDividerColor(npCounty);  
  108.         //設定字型顏色
  109.         setNumberPickerTextColor(npProvince, context.getResources().getColor(R.color.mainColor));  
  110.         setNumberPickerTextColor(npCity, context.getResources().getColor(R.color.mainColor));  
  111.         setNumberPickerTextColor(npCounty, context.getResources().getColor(R.color.mainColor));  
  112.     }  
  113.     @Override
  114.     publicvoid onClick(View v) {  
  115.         switch (v.getId()) {  
  116.             case R.id.tvCancel:  
  117.                 dialog.dismiss();  
  118.                 break;  
  119.             case R.id.tvSure:  
  120.                 dialog.dismiss();  
  121.                 cityInterface.sure(newCityArray);  
  122.                 break;  
  123.         }  
  124.     }  
  125.     //選擇器選擇值監聽
  126.     @Override
  127.     publicvoid onValueChange(NumberPicker picker, int oldVal, int newVal) {  
  128.         switch (picker.getId()) {  
  129.             case R.id.npProvince:  
  130.                 List<CityBean.Data> dataList = bean.getData();  
  131.                 newCityArray[0] = dataList.get(npProvince.getValue()).getName();  
  132.                 changeCity(npProvince.getValue());  
  133.                 newCityArray[1] = dataList.get(npProvince.getValue()).getCity().get(0).getName();  
  134.                 newCityArray[2] = dataList.get(npProvince.getValue()).getCity().get(0).getCounty().get(0).toString();  
  135.                 break;  
  136.             case R.id.npCity:  
  137.                 List<CityBean.Data.City> cityList = bean.getData().get(npProvince.getValue()).getCity();  
  138.                 newCityArray[1] = cityList.get(npCity.getValue()).getName();  
  139.                 changeCounty(npProvince.getValue(), npCity.getValue());  
  140.                 newCityArray[2] = cityList.get(npCity.getValue()).getCounty().get(0).toString();  
  141.                 break;  
  142.             case R.id.npCounty:  
  143.                 List<String> countyList = bean.getData().get(npProvince.getValue()).getCity().get(npCity.getValue()).getCounty();  
  144.                 newCityArray[2] = countyList.get(npCounty.getValue()).toString();  
  145.                 break;  
  146.         }  
  147.     }  
  148.     //設定分割線顏色
  149.     privatevoid setNumberPickerDividerColor(NumberPicker numberPicker) {  
  150.         NumberPicker picker = numberPicker;  
  151.         Field[] pickerFields = NumberPicker.class.getDeclaredFields();  
  152.         for (Field pf : pickerFields) {  
  153.             if (pf.getName().equals("mSelectionDivider")) {  
  154.                 pf.setAccessible(true);  
  155.                 try {  
  156.                     //設定分割線的顏色值
  157.                     pf.set(picker, new ColorDrawable(context.getResources().getColor(R.color.transparent)));// pf.set(picker, new Div)
  158.                 } catch (IllegalArgumentException e) {  
  159.                     e.printStackTrace();  
  160.                 } catch (Resources.NotFoundException e) {  
  161.                     e.printStackTrace();  
  162.                 } catch (IllegalAccessException e) {  
  163.                     e.printStackTrace();  
  164.                 }  
  165.                 break;  
  166.             }  
  167.         }  
  168.     }  
  169.     //設定選擇器字型顏色
  170.     publicstaticboolean setNumberPickerTextColor(NumberPicker numberPicker, int color) {  
  171.         boolean result = false;  
  172.         finalint count = numberPicker.getChildCount();  
  173.         for (int i = 0; i < count; i++) {  
  174.             View child = numberPicker.getChildAt(i);  
  175.             if (child instanceof EditText) {  
  176.                 try {  
  177.                     Field selectorWheelPaintField = numberPicker.getClass()  
  178.                             .getDeclaredField("mSelectorWheelPaint");  
  179.                     selectorWheelPaintField.setAccessible(true);  
  180.                     ((Paint) selectorWheelPaintField.get(numberPicker)).setColor(color);  
  181.                     ((EditText) child).setTextColor(color);  
  182.                     numberPicker.invalidate();  
  183.                     result = true;  
  184.                 } catch (NoSuchFieldException e) {  
  185.                     e.printStackTrace();  
  186.                 } catch (IllegalAccessException e) {  
  187.                     e.printStackTrace();  
  188.                 } catch (IllegalArgumentException e) {  
  189.                     e.printStackTrace();  
  190.                 }  
  191.             }  
  192.         }  
  193.         return result;  
  194.     }  
  195. }  

使用呼叫 MainActivity.java
  1. publicclass MainActivity extends Activity {  
  2.     TextView tvCity;//城市
  3.     @Override
  4.     protectedvoid onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.         initView();  
  8.     }  
  9.     //初始化控制元件
  10.     privatevoid initView() {  
  11.         tvCity = (TextView) findViewById(R.id.tvCity);  
  12.     }  
  13.     //Choose Date 選擇省市縣
  14.     publicvoid chooseCityDialog(View view) {  
  15.         final ChooseCityUtil cityUtil = new ChooseCityUtil();  
  16.         String[] oldCityArray = tvCity.getText().toString().split("-");//將TextView上的文字分割成陣列 當做預設值
  17.         cityUtil.createDialog(this, oldCityArray, new ChooseCityInterface() {  
  18.             @Override
  19.             publicvoid sure(String[] newCityArray) {  
  20.                 //oldCityArray為傳入的預設值 newCityArray為返回的結果
  21.                 tvCity.setText(newCityArray[0] + "-" + newCityArray[1] + "-" + newCityArray[2]);  
  22.             }  
  23.         });  
  24.     }  
  25. }  

顏色 colors.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.     <color name="mainColor">#1BC47A</color>  
  4.     <color name="gray">#EEEEEE</color>  
  5.     <color name="black">#5E5E5E</color>  
  6.     <color name="white">#FFF</color>  
  7.     <color name="transparent">#00000000</color>  
  8. </resources>  
省市縣Json資料類 CityData.java
  1. publicclass CityData {  
  2.     publicstatic String getJson() {  
  3.         return"轉譯符看著太亂,把下面的json資料複製到這裡,替換掉!";  
  4.     }  
  5. }  
  1. {  
  2.   "note""全國省市縣資料",  
  3.   "data": [  
  4.     {  
  5.       "name""北京",  
  6.       "city": [  
  7.         {  
  8.           "name""北京",  
  9.           "county": [  
  10.             "昌平",  
  11.             "朝陽",  
  12.             "大興",  
  13.             "房山",  
  14.             "豐臺",  
  15.             "海淀",  
  16.             "懷柔",  
  17.             "門頭溝",  
  18.             "密雲",  
  19.             "平谷",  
  20.             "石景山",  
  21.             "順義",  
  22.             "通州",  
  23.             "宣武",  
  24.             "延慶"
  25.           ]  
  26.         }  
  27.       ]  
  28.     },  
  29.     {  
  30.       "name""安徽",  
  31.       "city": [  
  32.         {  
  33.           "name""安慶",  
  34.           "county": [  
  35.             "大觀",  
  36.             "懷寧",  
  37.             "潛山",  
  38.             "宿松",  
  39.             "太湖",  
  40.             "桐城",  
  41.             "望江",  
  42.             "宜秀",  
  43.             "迎江",  
  44.             "嶽西",  
  45.             "樅陽"
  46.           ]  
  47.         },  
  48.         {  
  49.           "name""蚌埠",  
  50.           "county": [  
  51.             "蚌山",  
  52.             "固鎮",  
  53.             "淮上",  
  54.             "懷遠",  
  55.             "龍子湖",  
  56.             "五河",  
  57.             "禹會"
  58.           ]  
  59.         },  
  60.         {  
  61.           "name""亳州",  
  62.           "county": [  
  63.             "渦陽",  
  64.             "利辛",  
  65.             "蒙城",  
  66.             "譙城"
  67.           ]  
  68.         },  
  69.         {  
  70.           "name""巢湖",  
  71.           "county": [  
  72.             "含山",  
  73.             "和縣",  
  74.             "居巢",  
  75.             "廬江",  
  76.             "無為"
  77.           ]  
  78.         },  
  79.         {  
  80.           "name""池州",  
  81.           "county": [  
  82.             "東至",  
  83.             "貴池",  
  84.             "青陽",  
  85.             "石臺"
  86.           ]  
  87.         },  
  88.         {  
  89.           "name""滁州",  
  90.           "county": [  
  91.             "定遠",  
  92.             "鳳陽",  
  93.             "來安",  
  94.             "琅玡",  
  95.             "明光",  
  96.             "南譙",  
  97.             "全椒",  
  98.             "天長"
  99.           ]  
  100.         },  
  101.         {  
  102.           "name""阜陽",  
  103.           "county": [  
  104.             "阜南",  
  105.             "界首",  
  106.             "臨泉",  
  107.             "太和",  
  108.             "穎東",  
  109.             "穎泉",  
  110.             "潁上",  
  111.             "穎州"
  112.           ]  
  113.         },  
  114.         {  
  115.           "name""合肥",  
  116.           "county": [  
  117.             "包河",  
  118.             "長豐",  
  119.             "肥東",  
  120.             "肥西",  
  121.             "廬陽",  
  122.             "蜀山",  
  123.             "瑤海"
  124.           ]  
  125.         },  
  126.         {  
  127.           "name""淮北",  
  128.           "county": [  
  129.             "杜集",  
  130.             "烈山",  
  131.             "濉溪",  
  132.             "相山"
  133.           ]  
  134.         },  
  135.         {  
  136.           "name""淮南",  
  137.           "county": [  
  138.             "八公山",  
  139.             "大通",  
  140.             "鳳台",  
  141.             "潘集",  
  142.             "田家庵",  <