Android省市縣三級聯動 真實專案抽出 呼叫只需3行程式碼
阿新 • • 發佈:2019-02-06
- 專案原始碼:包含日期、省市縣兩種選擇器[資源積分:0分] ,APK安裝包下載,沒有CSDN賬戶的的點此下載原始碼
- fastjson:自己複製部落格裡原始碼的小夥伴,注意匯入fastjson框架哦!阿里巴巴出品的最快json解析框架
- 日期選擇器:效果圖中的選擇年月日的日期選擇器
- 任何問題,歡迎評論;原始碼下載不成功的留下郵箱;文章我還在維護,持續優化,有問題的小夥伴積極評論哈。
先上效果圖: 樣式可以修改xml檔案
- 省市縣三級聯動,選地址經常用到
- 原生NumberPicker控制元件實現滑動,json資料解析使用fastjson框架
- 使用簡單:傳入一個String[]陣列,設定選擇器的預設值,點選確認按鈕,回撥介面返回String[]陣列,為重新選擇的省市縣
- 隨意修改:效果圖中字型顏色佈局等都可以修改,以保證與你的專案風格統一
把我原始碼裡寫好的java檔案和xml檔案拷到你的專案中,呼叫就這麼簡單:
- ChooseCityUtil cityUtil = new ChooseCityUtil();
- String[] oldCityArray = {"廣東","深圳","福田"};
- cityUtil.createDialog(this, oldCityArray, new ChooseCityInterface() {
- @Override
- publicvoid sure(String[] newCityArray) {
- //oldCityArray為傳入的預設值 newCityArray為返回的結果
- tvCity.setText(newCityArray[0] + "-" + newCityArray[1] + "-" + newCityArray[2]);
- }
- });
-------------------------------------------------------- 我是分割線 --------------------------------------------------------
接下來看是如何實現的
佈局檔案activity_main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fitsSystemWindows="true"
- android:orientation="vertical"
- tools:context=".MainActivity">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="56dp"
- android:background="@color/mainColor"
- android:gravity="center"
- android:text="選擇器 Picker"
- android:textColor="@color/white"
- android:textSize="20sp" />
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:orientation="horizontal">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center"
- android:text="城市設定:"
- android:textColor="#656565"
- android:textSize="18sp" />
- <TextView
- android:id="@+id/tvCity"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentRight="true"
- android:clickable="true"
- android:gravity="center"
- android:onClick="chooseCityDialog"
- android:text="廣東-深圳-福田"
- android:textColor="#656565"
- android:textSize="18sp" />
- </RelativeLayout>
- <View
- android:layout_width="match_parent"
- android:layout_height="0.1dp"
- android:background="@color/gray" />
- </LinearLayout>
對話方塊佈局檔案 dialog_choose_city.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#00000000"
- android:gravity="center"
- android:orientation="vertical">
- <LinearLayout
- android:layout_width="260dp"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:background="#FFF">
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <NumberPicker
- android:id="@+id/npProvince"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="wrap_content"/>
- <TextView
- android:layout_width="wrap_content"
- android:layout_marginLeft="3dp"
- android:layout_marginRight="3dp"
- android:layout_height="match_parent"
- android:gravity="center"
- android:text="省"
- android:textColor="#656565"
- android:textSize="18sp" />
- <NumberPicker
- android:id="@+id/npCity"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="wrap_content" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_marginLeft="3dp"
- android:layout_marginRight="3dp"
- android:layout_height="match_parent"
- android:gravity="center"
- android:text="市"
- android:textColor="#656565"
- android:textSize="18sp" />
- <NumberPicker
- android:id="@+id/npCounty"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="wrap_content" />
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:gravity="center"
- android:text=""
- android:textColor="#656565"
- android:textSize="18sp" />
- </LinearLayout>
- <View
- android:layout_width="match_parent"
- android:layout_height="0.1dp"
- android:background="#EEEEEE"/>
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="50dp"
- android:orientation="horizontal">
- <TextView
- android:id="@+id/tvCancel"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center"
- android:text="取消"
- android:textColor="#656565"
- android:textSize="18sp" />
- <TextView
- android:id="@+id/tvSure"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center"
- android:text="確定"
- android:textColor="#656565"
- android:textSize="18sp" />
- </LinearLayout>
- </LinearLayout>
- </LinearLayout>
介面類ChooseCityInterface.java
- publicinterface ChooseCityInterface {
- publicvoid sure(String[] newCityArray);
- }
json對應實體類CityBean.java
- publicclass CityBean {
- private String note;
- private List<Data> data;
- public String getNote() {
- return note;
- }
- publicvoid setNote(String note) {
- this.note = note;
- }
- public List<Data> getData() {
- return data;
- }
- publicvoid setData(List<Data> data) {
- this.data = data;
- }
- publicstaticclass Data {
- private String name;
- private List<City> city;
- public String getName() {
- return name;
- }
- publicvoid setName(String name) {
- this.name = name;
- }
- public List<City> getCity() {
- return city;
- }
- publicvoid setCity(List<City> city) {
- this.city = city;
- }
- publicstaticclass City {
- private String name;
- private List<String> county;
- public String getName() {
- return name;
- }
- publicvoid setName(String name) {
- this.name = name;
- }
- public List<String> getCounty() {
- return county;
- }
- publicvoid setCounty(List<String> county) {
- this.county = county;
- }
- }
- }
- }
- publicclass ChooseCityUtil implements View.OnClickListener, NumberPicker.OnValueChangeListener {
- Context context;
- AlertDialog dialog;
- ChooseCityInterface cityInterface;
- NumberPicker npProvince, npCity, npCounty;
- TextView tvCancel, tvSure;
- String[] newCityArray = new String[3];
- CityBean bean;
- publicvoid createDialog(Context context, String[] oldCityArray, ChooseCityInterface cityInterface) {
- this.context = context;
- this.cityInterface = cityInterface;
- bean = JSON.parseObject(CityData.getJson(), CityBean.class);
- newCityArray[0] = oldCityArray[0];
- newCityArray[1] = oldCityArray[1];
- newCityArray[2] = oldCityArray[2];
- dialog = new AlertDialog.Builder(context).create();
- dialog.show();
- Window window = dialog.getWindow();
- window.setContentView(R.layout.dialog_choose_city);
- //初始化控制元件
- tvCancel = (TextView) window.findViewById(R.id.tvCancel);
- tvSure = (TextView) window.findViewById(R.id.tvSure);
- tvCancel.setOnClickListener(this);
- tvSure.setOnClickListener(this);
- npProvince = (NumberPicker) window.findViewById(R.id.npProvince);
- npCity = (NumberPicker) window.findViewById(R.id.npCity);
- npCounty = (NumberPicker) window.findViewById(R.id.npCounty);
- setNomal();
- //省:設定選擇器最小值、最大值、初始值
- String[] provinceArray = new String[bean.getData().size()];//初始化省陣列
- for (int i = 0; i < provinceArray.length; i++) {//省陣列填充資料
- provinceArray[i] = bean.getData().get(i).getName();
- }
- npProvince.setDisplayedValues(provinceArray);//設定選擇器資料、預設值
- npProvince.setMinValue(0);
- npProvince.setMaxValue(provinceArray.length - 1);
- for (int i = 0; i < provinceArray.length; i++) {
- if (provinceArray[i].equals(newCityArray[0])) {
- npProvince.setValue(i);
- changeCity(i);//聯動市資料
- }
- }
- }
- //根據省,聯動市資料
- privatevoid changeCity(int provinceTag) {
- List<CityBean.Data.City> cityList = bean.getData().get(provinceTag).getCity();
- String[] cityArray = new String[cityList.size()];
- for (int i = 0; i < cityArray.length; i++) {
- cityArray[i] = cityList.get(i).getName();
- }
- try {
- npCity.setMinValue(0);
- npCity.setMaxValue(cityArray.length - 1);
- npCity.setWrapSelectorWheel(false);
- npCity.setDisplayedValues(cityArray);//設定選擇器資料、預設值
- } catch (Exception e) {
- npCity.setDisplayedValues(cityArray);//設定選擇器資料、預設值
- npCity.setMinValue(0);
- npCity.setMaxValue(cityArray.length - 1);
- npCity.setWrapSelectorWheel(false);
- }
- for (int i = 0; i < cityArray.length; i++) {
- if (cityArray[i].equals(newCityArray[1])) {
- npCity.setValue(i);
- changeCounty(provinceTag, i);//聯動縣資料
- return;
- }
- }
- npCity.setValue(0);
- changeCounty(provinceTag, npCity.getValue());//聯動縣資料
- }
- //根據市,聯動縣資料
- privatevoid changeCounty(int provinceTag, int cityTag) {
- List<String> countyList = bean.getData().get(provinceTag).getCity().get(cityTag).getCounty();
- String[] countyArray = new String[countyList.size()];
- for (int i = 0; i < countyArray.length; i++) {
- countyArray[i] = countyList.get(i).toString();
- }
- try {
- npCounty.setMinValue(0);
- npCounty.setMaxValue(countyArray.length - 1);
- npCounty.setWrapSelectorWheel(false);
- npCounty.setDisplayedValues(countyArray);//設定選擇器資料、預設值
- } catch (Exception e) {
- npCounty.setDisplayedValues(countyArray);//設定選擇器資料、預設值
- npCounty.setMinValue(0);
- npCounty.setMaxValue(countyArray.length - 1);
- npCounty.setWrapSelectorWheel(false);
- }
- for (int i = 0; i < countyArray.length; i++) {
- if (countyArray[i].equals(newCityArray[2])) {
- npCounty.setValue(i);
- return;
- }
- }
- npCounty.setValue(0);
- }
- //設定NumberPicker的分割線透明、字型顏色、設定監聽
- privatevoid setNomal() {
- //設定監聽
- npProvince.setOnValueChangedListener(this);
- npCity.setOnValueChangedListener(this);
- npCounty.setOnValueChangedListener(this);
- //去除分割線
- setNumberPickerDividerColor(npProvince);
- setNumberPickerDividerColor(npCity);
- setNumberPickerDividerColor(npCounty);
- //設定字型顏色
- setNumberPickerTextColor(npProvince, context.getResources().getColor(R.color.mainColor));
- setNumberPickerTextColor(npCity, context.getResources().getColor(R.color.mainColor));
- setNumberPickerTextColor(npCounty, context.getResources().getColor(R.color.mainColor));
- }
- @Override
- publicvoid onClick(View v) {
- switch (v.getId()) {
- case R.id.tvCancel:
- dialog.dismiss();
- break;
- case R.id.tvSure:
- dialog.dismiss();
- cityInterface.sure(newCityArray);
- break;
- }
- }
- //選擇器選擇值監聽
- @Override
- publicvoid onValueChange(NumberPicker picker, int oldVal, int newVal) {
- switch (picker.getId()) {
- case R.id.npProvince:
- List<CityBean.Data> dataList = bean.getData();
- newCityArray[0] = dataList.get(npProvince.getValue()).getName();
- changeCity(npProvince.getValue());
- newCityArray[1] = dataList.get(npProvince.getValue()).getCity().get(0).getName();
- newCityArray[2] = dataList.get(npProvince.getValue()).getCity().get(0).getCounty().get(0).toString();
- break;
- case R.id.npCity:
- List<CityBean.Data.City> cityList = bean.getData().get(npProvince.getValue()).getCity();
- newCityArray[1] = cityList.get(npCity.getValue()).getName();
- changeCounty(npProvince.getValue(), npCity.getValue());
- newCityArray[2] = cityList.get(npCity.getValue()).getCounty().get(0).toString();
- break;
- case R.id.npCounty:
- List<String> countyList = bean.getData().get(npProvince.getValue()).getCity().get(npCity.getValue()).getCounty();
- newCityArray[2] = countyList.get(npCounty.getValue()).toString();
- break;
- }
- }
- //設定分割線顏色
- privatevoid setNumberPickerDividerColor(NumberPicker numberPicker) {
- NumberPicker picker = numberPicker;
- Field[] pickerFields = NumberPicker.class.getDeclaredFields();
- for (Field pf : pickerFields) {
- if (pf.getName().equals("mSelectionDivider")) {
- pf.setAccessible(true);
- try {
- //設定分割線的顏色值
- pf.set(picker, new ColorDrawable(context.getResources().getColor(R.color.transparent)));// pf.set(picker, new Div)
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (Resources.NotFoundException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- break;
- }
- }
- }
- //設定選擇器字型顏色
- publicstaticboolean setNumberPickerTextColor(NumberPicker numberPicker, int color) {
- boolean result = false;
- finalint count = numberPicker.getChildCount();
- for (int i = 0; i < count; i++) {
- View child = numberPicker.getChildAt(i);
- if (child instanceof EditText) {
- try {
- Field selectorWheelPaintField = numberPicker.getClass()
- .getDeclaredField("mSelectorWheelPaint");
- selectorWheelPaintField.setAccessible(true);
- ((Paint) selectorWheelPaintField.get(numberPicker)).setColor(color);
- ((EditText) child).setTextColor(color);
- numberPicker.invalidate();
- result = true;
- } catch (NoSuchFieldException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- }
- }
- }
- return result;
- }
- }
使用呼叫 MainActivity.java
- publicclass MainActivity extends Activity {
- TextView tvCity;//城市
- @Override
- protectedvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initView();
- }
- //初始化控制元件
- privatevoid initView() {
- tvCity = (TextView) findViewById(R.id.tvCity);
- }
- //Choose Date 選擇省市縣
- publicvoid chooseCityDialog(View view) {
- final ChooseCityUtil cityUtil = new ChooseCityUtil();
- String[] oldCityArray = tvCity.getText().toString().split("-");//將TextView上的文字分割成陣列 當做預設值
- cityUtil.createDialog(this, oldCityArray, new ChooseCityInterface() {
- @Override
- publicvoid sure(String[] newCityArray) {
- //oldCityArray為傳入的預設值 newCityArray為返回的結果
- tvCity.setText(newCityArray[0] + "-" + newCityArray[1] + "-" + newCityArray[2]);
- }
- });
- }
- }
顏色 colors.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <color name="mainColor">#1BC47A</color>
- <color name="gray">#EEEEEE</color>
- <color name="black">#5E5E5E</color>
- <color name="white">#FFF</color>
- <color name="transparent">#00000000</color>
- </resources>
- publicclass CityData {
- publicstatic String getJson() {
- return"轉譯符看著太亂,把下面的json資料複製到這裡,替換掉!";
- }
- }
- {
- "note": "全國省市縣資料",
- "data": [
- {
- "name": "北京",
- "city": [
- {
- "name": "北京",
- "county": [
- "昌平",
- "朝陽",
- "大興",
- "房山",
- "豐臺",
- "海淀",
- "懷柔",
- "門頭溝",
- "密雲",
- "平谷",
- "石景山",
- "順義",
- "通州",
- "宣武",
- "延慶"
- ]
- }
- ]
- },
- {
- "name": "安徽",
- "city": [
- {
- "name": "安慶",
- "county": [
- "大觀",
- "懷寧",
- "潛山",
- "宿松",
- "太湖",
- "桐城",
- "望江",
- "宜秀",
- "迎江",
- "嶽西",
- "樅陽"
- ]
- },
- {
- "name": "蚌埠",
- "county": [
- "蚌山",
- "固鎮",
- "淮上",
- "懷遠",
- "龍子湖",
- "五河",
- "禹會"
- ]
- },
- {
- "name": "亳州",
- "county": [
- "渦陽",
- "利辛",
- "蒙城",
- "譙城"
- ]
- },
- {
- "name": "巢湖",
- "county": [
- "含山",
- "和縣",
- "居巢",
- "廬江",
- "無為"
- ]
- },
- {
- "name": "池州",
- "county": [
- "東至",
- "貴池",
- "青陽",
- "石臺"
- ]
- },
- {
- "name": "滁州",
- "county": [
- "定遠",
- "鳳陽",
- "來安",
- "琅玡",
- "明光",
- "南譙",
- "全椒",
- "天長"
- ]
- },
- {
- "name": "阜陽",
- "county": [
- "阜南",
- "界首",
- "臨泉",
- "太和",
- "穎東",
- "穎泉",
- "潁上",
- "穎州"
- ]
- },
- {
- "name": "合肥",
- "county": [
- "包河",
- "長豐",
- "肥東",
- "肥西",
- "廬陽",
- "蜀山",
- "瑤海"
- ]
- },
- {
- "name": "淮北",
- "county": [
- "杜集",
- "烈山",
- "濉溪",
- "相山"
- ]
- },
- {
- "name": "淮南",
- "county": [
- "八公山",
- "大通",
- "鳳台",
- "潘集",
- "田家庵", <