android-wheel控件實現(xiàn)三級聯(lián)動效果
本文實例為大家分享了android wheel省市縣三級聯(lián)動效果,供大家參考,具體內容如下
在github上面有一個叫做 Android-wheel 的開源控件, 代碼地址:https://github.com/maarek/android-wheel

源碼下載地址:http://xiazai.jb51.net/201610/yuanma/AndroidCascadeMaster(jb51.net).rar
主界面布局
activity_main.xml
<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="wrap_content"
android:background="#E9E9E9"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<kankan.wheel.widget.WheelView
android:id="@+id/id_province"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" >
</kankan.wheel.widget.WheelView>
<kankan.wheel.widget.WheelView
android:id="@+id/id_city"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" >
</kankan.wheel.widget.WheelView>
<kankan.wheel.widget.WheelView
android:id="@+id/id_district"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" >
</kankan.wheel.widget.WheelView>
</LinearLayout>
<Button
android:id="@+id/btn_confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:gravity="center"
android:text="確定"
android:textColor="#000000" />
</LinearLayout>
assets資源文件下--province_data.xml(一部分)
<root> <province name="安徽省"> <city name="安慶市"> <district name="樅陽縣" zipcode="246000" /> <district name="大觀區(qū)" zipcode="246000" /> <district name="懷寧縣" zipcode="246000" /> <district name="潛山縣" zipcode="246000" /> <district name="宿松縣" zipcode="246000" /> <district name="太湖縣" zipcode="246000" /> <district name="桐城市" zipcode="246000" /> <district name="望江縣" zipcode="246000" /> <district name="宜秀區(qū)" zipcode="246000" /> <district name="迎江區(qū)" zipcode="246000" /> <district name="岳西縣" zipcode="246000" /> <district name="其他" zipcode="246000" /> </city>
先看省份、城市、縣鄉(xiāng)的bean類
ProvinceModel
package com.mrwujay.cascade.model;
import java.util.List;
public class ProvinceModel {
private String name;
private List<CityModel> cityList;
public ProvinceModel() {
super();
}
public ProvinceModel(String name, List<CityModel> cityList) {
super();
this.name = name;
this.cityList = cityList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<CityModel> getCityList() {
return cityList;
}
public void setCityList(List<CityModel> cityList) {
this.cityList = cityList;
}
@Override
public String toString() {
return "ProvinceModel [name=" + name + ", cityList=" + cityList + "]";
}
}
package com.mrwujay.cascade.model;
import java.util.List;
public class CityModel {
private String name;
private List<DistrictModel> districtList;
public CityModel() {
super();
}
public CityModel(String name, List<DistrictModel> districtList) {
super();
this.name = name;
this.districtList = districtList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<DistrictModel> getDistrictList() {
return districtList;
}
public void setDistrictList(List<DistrictModel> districtList) {
this.districtList = districtList;
}
@Override
public String toString() {
return "CityModel [name=" + name + ", districtList=" + districtList
+ "]";
}
}
DistrictModel
package com.mrwujay.cascade.model;
public class DistrictModel {
private String name;
private String zipcode;
public DistrictModel() {
super();
}
public DistrictModel(String name, String zipcode) {
super();
this.name = name;
this.zipcode = zipcode;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
@Override
public String toString() {
return "DistrictModel [name=" + name + ", zipcode=" + zipcode + "]";
}
}
看自定義的XmlParserHandler
package com.mrwujay.cascade.service;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.mrwujay.cascade.model.CityModel;
import com.mrwujay.cascade.model.DistrictModel;
import com.mrwujay.cascade.model.ProvinceModel;
public class XmlParserHandler extends DefaultHandler {
/**
* 存儲所有的解析對象
*/
private List<ProvinceModel> provinceList = new ArrayList<ProvinceModel>();
public XmlParserHandler() {
}
/**
* 對外暴露的方法
*/
public List<ProvinceModel> getDataList() {
return provinceList;
}
@Override
public void startDocument() throws SAXException {
// 當讀到第一個開始標簽的時候,會觸發(fā)這個方法
}
ProvinceModel provinceModel = new ProvinceModel();
CityModel cityModel = new CityModel();
DistrictModel districtModel = new DistrictModel();
/**
* <province name="安徽省">
<city name="安慶市">
<district name="樅陽縣" zipcode="246000" />
<district name="大觀區(qū)" zipcode="246000" />
<district name="懷寧縣" zipcode="246000" />
<district name="潛山縣" zipcode="246000" />
<district name="宿松縣" zipcode="246000" />
<district name="太湖縣" zipcode="246000" />
<district name="桐城市" zipcode="246000" />
<district name="望江縣" zipcode="246000" />
<district name="宜秀區(qū)" zipcode="246000" />
<district name="迎江區(qū)" zipcode="246000" />
<district name="岳西縣" zipcode="246000" />
<district name="其他" zipcode="246000" />
</city>
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// 當遇到開始標記的時候,調用這個方法
if (qName.equals("province")) {
provinceModel = new ProvinceModel();
provinceModel.setName(attributes.getValue(0));
provinceModel.setCityList(new ArrayList<CityModel>());
} else if (qName.equals("city")) {
cityModel = new CityModel();
cityModel.setName(attributes.getValue(0));
cityModel.setDistrictList(new ArrayList<DistrictModel>());
} else if (qName.equals("district")) {
districtModel = new DistrictModel();
districtModel.setName(attributes.getValue(0));
districtModel.setZipcode(attributes.getValue(1));
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// 遇到結束標記的時候,會調用這個方法
if (qName.equals("district")) {
cityModel.getDistrictList().add(districtModel);
} else if (qName.equals("city")) {
provinceModel.getCityList().add(cityModel);
} else if (qName.equals("province")) {
provinceList.add(provinceModel);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
}
}
接下來看基類BaseActivity
package com.mrwujay.cascade.activity;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import android.app.Activity;
import android.content.res.AssetManager;
import com.mrwujay.cascade.model.CityModel;
import com.mrwujay.cascade.model.DistrictModel;
import com.mrwujay.cascade.model.ProvinceModel;
import com.mrwujay.cascade.service.XmlParserHandler;
public class BaseActivity extends Activity {
/**
* 所有省
*/
protected String[] mProvinceDatas;
/**
* key - 省 value - 市
*/
protected Map<String, String[]> mCitisDatasMap = new HashMap<String, String[]>();
/**
* key - 市 values - 區(qū)
*/
protected Map<String, String[]> mDistrictDatasMap = new HashMap<String, String[]>();
/**
* key - 區(qū) values - 郵編
*/
protected Map<String, String> mZipcodeDatasMap = new HashMap<String, String>();
/**
* 當前省的名稱
*/
protected String mCurrentProviceName;
/**
* 當前市的名稱
*/
protected String mCurrentCityName;
/**
* 當前區(qū)的名稱
*/
protected String mCurrentDistrictName = "";
/**
* 當前區(qū)的郵政編碼
*/
protected String mCurrentZipCode = "";
/**
* 解析省市區(qū)的XML數(shù)據(jù)
*/
protected void initProvinceDatas() {
//省份集合列表
List<ProvinceModel> provinceList = null;
//獲取資源
AssetManager asset = getAssets();
try {
//獲取輸入流
InputStream input = asset.open("province_data.xml");
// 創(chuàng)建一個解析xml的工廠對象
SAXParserFactory spf = SAXParserFactory.newInstance();
// 解析xml
SAXParser parser = spf.newSAXParser();
//解析工具
XmlParserHandler handler = new XmlParserHandler();
//進行解析
parser.parse(input, handler);
input.close();
// 獲取解析出來的數(shù)據(jù)
provinceList = handler.getDataList();
// */ 初始化默認選中的省、市、區(qū)
if (provinceList != null && !provinceList.isEmpty()) {
//獲取第一個省份
mCurrentProviceName = provinceList.get(0).getName();
List<CityModel> cityList = provinceList.get(0).getCityList();
if (cityList != null && !cityList.isEmpty()) {
//獲取第一個省份的第一個城市名
mCurrentCityName = cityList.get(0).getName();
List<DistrictModel> districtList = cityList.get(0)
.getDistrictList();
//獲取第一個省份的第一個城市的第一個縣名稱
mCurrentDistrictName = districtList.get(0).getName();
mCurrentZipCode = districtList.get(0).getZipcode();
}
}
// */
mProvinceDatas = new String[provinceList.size()];
for (int i = 0; i < provinceList.size(); i++) {
// 遍歷所有省的數(shù)據(jù)
mProvinceDatas[i] = provinceList.get(i).getName();
List<CityModel> cityList = provinceList.get(i).getCityList();
String[] cityNames = new String[cityList.size()];
for (int j = 0; j < cityList.size(); j++) {
// 遍歷省下面的所有市的數(shù)據(jù)
cityNames[j] = cityList.get(j).getName();
List<DistrictModel> districtList = cityList.get(j)
.getDistrictList();
String[] distrinctNameArray = new String[districtList
.size()];
DistrictModel[] distrinctArray = new DistrictModel[districtList
.size()];
for (int k = 0; k < districtList.size(); k++) {
// 遍歷市下面所有區(qū)/縣的數(shù)據(jù)
DistrictModel districtModel = new DistrictModel(
districtList.get(k).getName(), districtList
.get(k).getZipcode());
// 區(qū)/縣對于的郵編,保存到mZipcodeDatasMap
mZipcodeDatasMap.put(districtList.get(k).getName(),
districtList.get(k).getZipcode());
distrinctArray[k] = districtModel;
distrinctNameArray[k] = districtModel.getName();
}
// 市-區(qū)/縣的數(shù)據(jù),保存到mDistrictDatasMap
mDistrictDatasMap.put(cityNames[j], distrinctNameArray);
}
// 省-市的數(shù)據(jù),保存到mCitisDatasMap
mCitisDatasMap.put(provinceList.get(i).getName(), cityNames);
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
}
}
}
主界面MainActivity
package com.mrwujay.cascade.activity;
import com.mrwujay.cascade.R;
import com.mrwujay.cascade.R.id;
import com.mrwujay.cascade.R.layout;
import kankan.wheel.widget.OnWheelChangedListener;
import kankan.wheel.widget.WheelView;
import kankan.wheel.widget.adapters.ArrayWheelAdapter;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends BaseActivity implements OnClickListener, OnWheelChangedListener {
private WheelView mViewProvince;
private WheelView mViewCity;
private WheelView mViewDistrict;
private Button mBtnConfirm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpViews();
setUpListener();
setUpData();
}
private void setUpViews() {
mViewProvince = (WheelView) findViewById(R.id.id_province);
mViewCity = (WheelView) findViewById(R.id.id_city);
mViewDistrict = (WheelView) findViewById(R.id.id_district);
mBtnConfirm = (Button) findViewById(R.id.btn_confirm);
}
private void setUpListener() {
// 添加change事件
mViewProvince.addChangingListener(this);
// 添加change事件
mViewCity.addChangingListener(this);
// 添加change事件
mViewDistrict.addChangingListener(this);
// 添加onclick事件
mBtnConfirm.setOnClickListener(this);
}
private void setUpData() {
initProvinceDatas();
mViewProvince.setViewAdapter(new ArrayWheelAdapter<String>(MainActivity.this, mProvinceDatas));
// 設置可見條目數(shù)量
mViewProvince.setVisibleItems(7);
mViewCity.setVisibleItems(7);
mViewDistrict.setVisibleItems(7);
updateCities();
updateAreas();
}
/**
* 根據(jù)當前的省,更新市WheelView的信息
*/
private void updateCities() {
//獲取當前的省份的itme索引值
int pCurrent = mViewProvince.getCurrentItem();
//湖區(qū)當前省份名字
mCurrentProviceName = mProvinceDatas[pCurrent];
//獲取該省份下面的市數(shù)組集合
String[] cities = mCitisDatasMap.get(mCurrentProviceName);
if (cities == null) {
cities = new String[] { "" };
}
mViewCity.setViewAdapter(new ArrayWheelAdapter<String>(this, cities));
mViewCity.setCurrentItem(0);
updateAreas();
}
/**
* 根據(jù)當前的市,更新區(qū)WheelView的信息
*/
private void updateAreas() {
int pCurrent = mViewCity.getCurrentItem();
mCurrentCityName = mCitisDatasMap.get(mCurrentProviceName)[pCurrent];
String[] areas = mDistrictDatasMap.get(mCurrentCityName);
if (areas == null) {
areas = new String[] { "" };
}
mViewDistrict.setViewAdapter(new ArrayWheelAdapter<String>(this, areas));
mViewDistrict.setCurrentItem(0);
}
/**
* 實現(xiàn)接口方法的回調
*/
@Override
public void onChanged(WheelView wheel, int oldValue, int newValue) {
// TODO Auto-generated method stub
if (wheel == mViewProvince) {
updateCities();
} else if (wheel == mViewCity) {
updateAreas();
} else if (wheel == mViewDistrict) {
//獲取縣的名字
mCurrentDistrictName = mDistrictDatasMap.get(mCurrentCityName)[newValue];
//獲取縣的編碼
mCurrentZipCode = mZipcodeDatasMap.get(mCurrentDistrictName);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_confirm:
showSelectedResult();
break;
default:
break;
}
}
private void showSelectedResult() {
Toast.makeText(MainActivity.this, "當前選中:"+mCurrentProviceName+","+mCurrentCityName+","
+mCurrentDistrictName+","+mCurrentZipCode, Toast.LENGTH_SHORT).show();
}
}
還有2個drawable
wheel_bg.xml
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> </layer-list>
wheel_val.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="90"
android:centerColor="#70222222"
android:endColor="#70EEEEEE"
android:startColor="#70222222" />
<stroke
android:width="20dp"
android:color="#FF69B4" />
</shape>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
- Android PickerView實現(xiàn)三級聯(lián)動效果
- Android實現(xiàn)省市區(qū)三級聯(lián)動
- 最好用的Android省市區(qū)三級聯(lián)動選擇效果
- Android日期選擇器實現(xiàn)年月日三級聯(lián)動
- Android中使用開源框架Citypickerview實現(xiàn)省市區(qū)三級聯(lián)動選擇
- Android自定義WheelView地區(qū)選擇三級聯(lián)動
- Android省市區(qū)三級聯(lián)動控件使用方法實例講解
- Android使用android-wheel實現(xiàn)省市縣三級聯(lián)動
- Android實現(xiàn)聯(lián)動下拉框 下拉列表spinner的實例代碼
- Android實現(xiàn)城市選擇三級聯(lián)動
相關文章
基于Android MarginLeft與MarginStart的區(qū)別(詳解)
下面小編就為大家分享一篇基于Android MarginLeft與MarginStart的區(qū)別(詳解),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
Android實現(xiàn)從底部彈出的Dialog的實例代碼
這篇文章主要介紹了Android實現(xiàn)從底部彈出的Dialog的實例代碼,非常不錯,具有參考借鑒價值 ,需要的朋友可以參考下2018-04-04
Android開發(fā)-之監(jiān)聽button點擊事件的多種方法
本篇文章主要是介紹了Android開發(fā)之監(jiān)聽button點擊事件的方法,Android開發(fā)-之監(jiān)聽button點擊事件的方法總結,有興趣的可以了解一下。2016-11-11

