此三级联动的实现基于pickerview,附上github地址:Android-PickerView
这是一款仿iOS的PickerView控件,有时间选择和选项选择,并支持一二三级联动,支持自定义样式。
首先下载pickerview,将其作为Module添加进你的项目
我使用的as,xutils框架,因为我的数据内容跟原作者的不一样,所以获取的方法不一样。
我的一组数据如下,省市区文件以txt文本的方式放在assets目录下
建立一个表存取省市区数据
Region.class
import org.xutils.db.annotation.Column; import org.xutils.db.annotation.Table; @Table(name = "region") public class Region { @Column(name = "id", isId = true) private int id; @Column(name = "pid") private int pid; @Column(name = "name") private String name; @Column(name = "type") private int type; public Region(int _id, int _pid, String _name, int _type) { this.id = _id; this.name = _name; this.type = _type; this.pid = _pid; } public Region() { this.id = 0; this.pid = 0; this.name = ""; this.type = 0; } @Override public String toString() { return "Region{" + "id=" + id + ", pid=" + pid + ", name='" + name + '\'' + ", type=" + type + '}'; } public int getId() { return id; } public int getPid() { return pid; } public String getName() { if (name == null) { name = ""; } return name; } public int getType() { return type; } public void setId(int id) { this.id = id; } public void setPid(int pid) { this.pid = pid; } public void setName(String name) { this.name = name; } public void setType(int type) { this.type = type; } }
在app启动的时候,将数据插入表内
try { JSONObject jsonObject = new JSONObject(getFromAssets("addr.txt")); JSONArray jsonArray = jsonObject.getJSONArray("data"); SystemConfig sysConfig = db.selector(SystemConfig.class).where("_key", "=", "region").findFirst();// 查询数据库内是否存在表region if (sysConfig == null) {// 不存在则创建 for (int i = 0; i < jsonArray.length(); i++) {// jsonArray.length()==3409 JSONArray array = jsonArray.getJSONArray(i); Region region = new Region(array.getInt(0), array.getInt(1), array.getString(2), array.getInt(3)); db.save(region); } db.save(new SystemConfig("region", jsonArray.length() + "")); } } catch (JSONException e) { e.printStackTrace(); } catch (DbException e) { e.printStackTrace(); }
//从assets 文件夹中获取文件并读取数据 public String getFromAssets(String fileName) { String result = ""; try { InputStream in = getResources().getAssets().open(fileName); //获取文件的字节数 int lenght = in.available(); //创建byte数组 byte[] buffer = new byte[lenght]; //将文件中的数据读到byte数组中 in.read(buffer); result = new String(buffer, "GBK"); } catch (Exception e) { e.printStackTrace(); } return result; }
数据已经准备好了,接下来在需要弹出选择器的页面进行操作
private String idProvince;// 省id private String idCity;// 市id private String idArea;// 区id private ArrayListactivity创建的时候对集合赋值options1Items = new ArrayList<>();// 省集合 private ArrayList > options2Items = new ArrayList<>();// 市集合 private ArrayList >> options3Items = new ArrayList<>();// 区集合
private void initData() { try { Listprovince = db.selector(Region.class).where("type", "=", 1).findAll(); for (int i = 0; i < province.size(); i++) {//遍历省份 options1Items.add(province.get(i).getName()); idProvince = province.get(i).getId() + ""; ArrayList CityList = new ArrayList<>();//该省的城市列表(第二级) ArrayList > Province_AreaList = new ArrayList<>();//该省的所有地区列表(第三极) List city = db.selector(Region.class).where("pid", "=", idProvince).and("type", "=", 2).findAll(); for (int c = 0; c < city.size(); c++) {//遍历该省份的所有城市 CityList.add(city.get(c).getName());//添加城市 idCity = city.get(c).getId() + ""; ArrayList City_AreaList = new ArrayList<>();//该城市的所有地区列表 List area = db.selector(Region.class).where("pid", "=", idCity).and("type", "=", 3).findAll(); //如果无地区数据,建议添加空字符串,防止数据为null 导致三个选项长度不匹配造成崩溃 if (area.size() == 0) { City_AreaList.add(""); } else { for (int d = 0; d < area.size(); d++) {//该城市对应地区所有数据 City_AreaList.add(area.get(d).getName());//添加该城市所有地区数据 } } Province_AreaList.add(City_AreaList);//添加该省所有地区数据 } /** * 添加城市数据 */ options2Items.add(CityList); /** * 添加地区数据 */ options3Items.add(Province_AreaList); } } catch (DbException e) { e.printStackTrace(); } }
点击事件
case R.id.ll_home:// 居住地选择 ShowPickerView(); break;
private void ShowPickerView() {// 弹出选择器 OptionsPickerView pvOptions = new OptionsPickerView.Builder(this, new OptionsPickerView.OnOptionsSelectListener() { @Override public void onOptionsSelect(int options1, int options2, int options3, View v) { //返回的分别是三个级别的选中位置 String tx = options1Items.get(options1) + options2Items.get(options1).get(options2) + options3Items.get(options1).get(options2).get(options3); } }) .setTitleText("城市选择") .setDividerColor(Color.BLACK) .setTextColorCenter(Color.BLACK) //设置选中项文字颜色 .setContentTextSize(20) .setOutSideCancelable(false)// default is true .build(); pvOptions.setPicker(options1Items, options2Items, options3Items);//三级选择器 pvOptions.show(); }
完成。