
通过WheelView来实现省市县三级联动
首先要创建三个实体类:
provinceInfo,cityInfo,districtInfo
准备开始写!!!
//此处调用
case R.id.edit_address_choose:
chooseAddress();//选择地址
break;
弹出地址选择框
//选择地址
private PopWindowLoader popWindowLoader;
private WheelView address_province;
private WheelView address_city;
private WheelView address_county;
private TextView address_cancel,address_sure;
public void chooseAddress(){
popWindowLoader = new PopWindowLoader(this,R.layout.addr_picker);
popWindowLoader.init(this, ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT,0xffffff);
popWindowLoader.setAnimationStyle(R.style.share_show_miss_Animation);
address_province = popWindowLoader.findViewById(R.id.address_province);
address_city = popWindowLoader.findViewById(R.id.address_city);
address_county = popWindowLoader.findViewById(R.id.address_county);
address_cancel = popWindowLoader.findViewById(R.id.address_cancel);
address_sure = popWindowLoader.findViewById(R.id.address_sure);
//省
address_province.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
String provinceText = mProvinceDatas.get(id);
if (!mCurrentProviceName.equals(provinceText)){
mCurrentProviceName = provinceText;
ArrayList<String> mCityData = mCitisDatasMap.get(mCurrentProviceName);
address_city.resetData(mCityData);//重置市数据集合
address_city.setDefault(0);
mCurrentCityName = mCityData.get(0);
ArrayList<String> mDistrictData = mDistrictDatasMap.get(mCurrentCityName);
address_county.resetData(mDistrictData);//重置县数据集合
address_county.setDefault(0);
mCurrentDistrictName = mDistrictData.get(0);
}
}
@Override
public void selecting(int id, String text) {
}
});
address_city.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
ArrayList<String> mCityData = mCitisDatasMap.get(mCurrentProviceName);
String cityText = mCityData.get(id);
if (!mCurrentCityName.equals(cityText)) {
mCurrentCityName = cityText;
ArrayList<String> mCountyData = mDistrictDatasMap.get(mCurrentCityName);
address_county.resetData(mCountyData);//重置县数据集合
address_county.setDefault(0);
mCurrentDistrictName = mCountyData.get(0);
}
}
@Override
public void selecting(int id, String text) {
}
});
address_county.setOnSelectListener(new WheelView.OnSelectListener() {
@Override
public void endSelect(int id, String text) {
ArrayList<String> mDistrictData = mDistrictDatasMap.get(mCurrentCityName);
String districtText = mDistrictData.get(id);
if (!mCurrentDistrictName.equals(districtText)) {
mCurrentDistrictName = districtText;
}
}
@Override
public void selecting(int id, String text) {
}
});
address_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popWindowLoader.dismiss();
}
});
address_sure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String addr = mCurrentProviceName + mCurrentCityName;
if (!mCurrentDistrictName.equals("其他")) {
addr += mCurrentDistrictName;
}
edit_address_choose_message.setText(addr);
popWindowLoader.dismiss();
}
});
//设置默认数据
new Thread() {
@Override
public void run() {
isDataLoaded = readAddrData();
Log.d(TAG, "isDataLoaded: " +isDataLoaded);
// 通知界面线程
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
address_province.setData(mProvinceDatas);//设置数据集合
address_province.setDefault(0);
mCurrentProviceName = mProvinceDatas.get(0);
ArrayList<String> mCityData = mCitisDatasMap.get(mCurrentProviceName);
address_city.setData(mCityData);//设置数据集合
address_city.setDefault(0);
mCurrentCityName = mCityData.get(0);
ArrayList<String> mDistrictData = mDistrictDatasMap.get(mCurrentCityName);
address_county.setData(mDistrictData);//设置数据集合
address_county.setDefault(0);
mCurrentDistrictName = mDistrictData.get(0);
}
});
}
}.start();
if (isDataLoaded){
popWindowLoader.showAtLocation(AddressManagerActivity.this, Gravity.CENTER | Gravity.BOTTOM, 0, 0);
}else {
ToastUtil.showToast2(this,"正在加载!");
}
}
//读取数据
private boolean readAddrData(){
List<ProvinceInfo> provinceInfoList ;
AssetManager asset = getAssets();
try {
InputStream input= asset.open("province_data.xml");
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser();
AddrXmlParser handler = new AddrXmlParser();
parser.parse(input, handler);//解析数据
input.close();
provinceInfoList = handler.getList();
//设置当前省市县名称
if (provinceInfoList != null && provinceInfoList.isEmpty()){
mCurrentProviceName = provinceInfoList.get(0).getName();//省
List<CityInfo> cityList = provinceInfoList.get(0).getCityList();
if (cityList != null && !cityList.isEmpty()) {
mCurrentCityName = cityList.get(0).getName();//市
List<DistrictInfo> districtList = cityList.get(0).getDistrictInfo();
mCurrentDistrictName = districtList.get(0).getName();//县
}
}
//构建数据源
mProvinceDatas = new ArrayList<>();
for (int i = 0;i<provinceInfoList.size();i ++){
mProvinceDatas.add(provinceInfoList.get(i).getName());//省数据数据源
List<CityInfo> cityList = provinceInfoList.get(i).getCityList();
ArrayList<String> cityName = new ArrayList<>();
for (int j=0;j<cityList.size();j++){
cityName.add(cityList.get(j).getName());
List<DistrictInfo> districtList = cityList.get(j).getDistrictInfo();
ArrayList<String> distrinctNameArray = new ArrayList<String>();
for (int k=0;k<districtList.size();k++){
distrinctNameArray.add(districtList.get(k).getName());
}
mDistrictDatasMap.put(cityName.get(j),distrinctNameArray);//县数据源
}
mCitisDatasMap.put(provinceInfoList.get(i).getName(),cityName);//市数据源
}
// Log.d(TAG, "mProvinceDatas: " + mProvinceDatas);
// Log.d(TAG, "mDistrictDatasMap: " +mDistrictDatasMap);
// Log.d(TAG, "mCitisDatasMap: " +mCitisDatasMap);
return true;
} catch (Throwable e) {
e.printStackTrace();
return false;
}
}
创建解析的类AddrXmlParser
public class AddrXmlParser extends DefaultHandler {
private List<ProvinceInfo> provinceList = new ArrayList<>();
public List<ProvinceInfo> getList(){
return provinceList;
}
private ProvinceInfo provinceInfo = new ProvinceInfo();
private CityInfo cityInfo = new CityInfo();
private DistrictInfo districtInfo = new DistrictInfo();
@Override
public void startDocument() throws SAXException {
super.startDocument();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if (qName.equals("province")){
provinceInfo = new ProvinceInfo();
provinceInfo.setName(attributes.getValue(0));
provinceInfo.setCityList(new ArrayList<CityInfo>());
}else if (qName.equals("city")){
cityInfo = new CityInfo();
cityInfo.setName(attributes.getValue(0));
cityInfo.setDistrictInfo(new ArrayList<DistrictInfo>());
}else if (qName.equals("district")){
districtInfo = new DistrictInfo();
districtInfo.setName(attributes.getValue(0));
districtInfo.setZipcode(attributes.getType(1));
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if (qName.equals("district")){
cityInfo.getDistrictInfo().add(districtInfo);
}else if (qName.equals("city")){
provinceInfo.getCityList().add(cityInfo);
}else if (qName.equals("province")){
provinceList.add(provinceInfo);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
}
}
下面是XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<!--xmlns:app="http://schemas.android.com/apk/res-auto" 为自定义属性标签,必须的有,不然报错-->
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/address_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="18sp"
android:clickable="true"
android:padding="5dp"
android:text="取消"/>
<TextView
android:id="@+id/address_sure"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="18sp"
android:clickable="true"
android:padding="5dp"
android:gravity="right"
android:text="确定"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.btsj.hpx.view.WheelView
android:id="@+id/address_province"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
app:itemNumber="3"
app:lineColor="#cccccc"
app:lineHeight="1.5dp"
app:maskHight="32dp"
app:noEmpty="true"
app:normalTextColor="#777"
app:normalTextSize="14sp"
app:selectedTextColor="#ff000000"
app:selectedTextSize="22sp"
app:unitHight="50dp" />
<com.btsj.hpx.view.WheelView
android:id="@+id/address_city"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
app:itemNumber="3"
app:lineColor="#cccccc"
app:lineHeight="1.5dp"
app:maskHight="32dp"
app:noEmpty="true"
app:normalTextColor="#777"
app:normalTextSize="14sp"
app:selectedTextColor="#ff000000"
app:selectedTextSize="22sp"
app:unitHight="50dp" />
<com.btsj.hpx.view.WheelView
android:id="@+id/address_county"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
app:itemNumber="3"
app:lineColor="#cccccc"
app:lineHeight="1.5dp"
app:maskHight="32dp"
app:noEmpty="true"
app:normalTextColor="#777"
app:normalTextSize="14sp"
app:selectedTextColor="#ff000000"
app:selectedTextSize="22sp"
app:unitHight="50dp" />
</LinearLayout>
</LinearLayout>
内部以app开头的都是自定义的属性
<declare-styleable name="WheelView">
<attr name="normalTextColor" format="color" />
<attr name="normalTextSize" format="dimension" />
<attr name="selectedTextColor" format="color" />
<attr name="selectedTextSize" format="dimension" />
<attr name="unitHight" format="dimension" />
<attr name="itemNumber" format="integer" />
<attr name="lineColor" format="color" />
<attr name="lineHeight" format="dimension" />
<attr name="maskHight" format="dimension" />
<attr name="noEmpty" format="boolean" />
<attr name="isEnable" format="boolean" />
</declare-styleable>
网友评论