android-wheel控件实现三级联动效果

本文实例为大家分享了android wheel省市县三级联动效果,供大家参考,具体内容如下

在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="大观区" 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="宜秀区" zipcode="246000" /> 
   <district name="迎江区" zipcode="246000" /> 
   <district name="岳西县" zipcode="246000" /> 
   <district name="其他" zipcode="246000" /> 
  </city> 

先看省份、城市、县乡的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 { 
    // 当读到第一个开始标签的时候,会触发这个方法 
  } 
 
  ProvinceModel provinceModel = new ProvinceModel(); 
  CityModel cityModel = new CityModel(); 
  DistrictModel districtModel = new DistrictModel(); 
/** 
 *  <province name="安徽省"> 
  <city name="安庆市"> 
   <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="桐城市" zipcode="246000" /> 
   <district name="望江县" zipcode="246000" /> 
   <district name="宜秀区" zipcode="246000" /> 
   <district name="迎江区" 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 - 区 
   */ 
  protected Map<String, String[]> mDistrictDatasMap = new HashMap<String, String[]>(); 
 
  /** 
   * key - 区 values - 邮编 
   */ 
  protected Map<String, String> mZipcodeDatasMap = new HashMap<String, String>(); 
 
  /** 
   * 当前省的名称 
   */ 
  protected String mCurrentProviceName; 
  /** 
   * 当前市的名称 
   */ 
  protected String mCurrentCityName; 
  /** 
   * 当前区的名称 
   */ 
  protected String mCurrentDistrictName = ""; 
 
  /** 
   * 当前区的邮政编码 
   */ 
  protected String mCurrentZipCode = ""; 
 
  /** 
   * 解析省市区的XML数据 
   */ 
 
  protected void initProvinceDatas() { 
    //省份集合列表 
    List<ProvinceModel> provinceList = null; 
    //获取资源 
    AssetManager asset = getAssets(); 
    try { 
      //获取输入流 
      InputStream input = asset.open("province_data.xml"); 
      // 创建一个解析xml的工厂对象 
      SAXParserFactory spf = SAXParserFactory.newInstance(); 
      // 解析xml 
      SAXParser parser = spf.newSAXParser(); 
      //解析工具 
      XmlParserHandler handler = new XmlParserHandler(); 
      //进行解析 
      parser.parse(input, handler); 
      input.close(); 
      // 获取解析出来的数据 
      provinceList = handler.getDataList(); 
      // */ 初始化默认选中的省、市、区 
      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++) { 
        // 遍历所有省的数据 
        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++) { 
          // 遍历省下面的所有市的数据 
          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++) { 
            // 遍历市下面所有区/县的数据 
            DistrictModel districtModel = new DistrictModel( 
                districtList.get(k).getName(), districtList 
                    .get(k).getZipcode()); 
            // 区/县对于的邮编,保存到mZipcodeDatasMap 
            mZipcodeDatasMap.put(districtList.get(k).getName(), 
                districtList.get(k).getZipcode()); 
            distrinctArray[k] = districtModel; 
            distrinctNameArray[k] = districtModel.getName(); 
          } 
          // 市-区/县的数据,保存到mDistrictDatasMap 
          mDistrictDatasMap.put(cityNames[j], distrinctNameArray); 
        } 
        // 省-市的数据,保存到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)); 
    // 设置可见条目数量 
    mViewProvince.setVisibleItems(7); 
    mViewCity.setVisibleItems(7); 
    mViewDistrict.setVisibleItems(7); 
    updateCities(); 
    updateAreas(); 
  } 
 
  /** 
   * 根据当前的省,更新市WheelView的信息 
   */ 
  private void updateCities() { 
    //获取当前的省份的itme索引值 
    int pCurrent = mViewProvince.getCurrentItem(); 
    //湖区当前省份名字 
    mCurrentProviceName = mProvinceDatas[pCurrent]; 
    //获取该省份下面的市数组集合 
    String[] cities = mCitisDatasMap.get(mCurrentProviceName); 
    if (cities == null) { 
      cities = new String[] { "" }; 
    } 
    mViewCity.setViewAdapter(new ArrayWheelAdapter<String>(this, cities)); 
    mViewCity.setCurrentItem(0); 
    updateAreas(); 
  } 
  /** 
   * 根据当前的市,更新区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); 
  } 
 
   
   
  /** 
   * 实现接口方法的回调 
   */ 
  @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> 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。