此三级联动的实现基于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;// 省idactivity创建的时候对集合赋值
private String idCity;// 市id
private String idArea;// 区id
private ArrayList<String> options1Items = new ArrayList<>();// 省集合
private ArrayList<ArrayList<String>> options2Items = new ArrayList<>();// 市集合
private ArrayList<ArrayList<ArrayList<String>>> options3Items = new ArrayList<>();// 区集合
private void initData() {
try {
List<Region> province = 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<String> CityList = new ArrayList<>();//该省的城市列表(第二级)
ArrayList<ArrayList<String>> Province_AreaList = new ArrayList<>();//该省的所有地区列表(第三极)
List<Region> 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<String> City_AreaList = new ArrayList<>();//该城市的所有地区列表
List<Region> 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();
}
完成。