很多应用都会用到地区选择,有些是直接选择城市(例如大众点评、58同城等),有些是先选择省再选择城市(例如微信),这里要做的是类似微信的做法,先选择省份再选择城市。
效果图:
地区数据格式(文件为city.json,保存在assets文件夹下):
先解析出数据,保存为list:
public List<String> getProvinceList() {
List<String> provinceList = new ArrayList<String>();// 省份
String json = getData().toString();
try {
JSONArray data = new JSONArray(json);
for (int i = 0; i < data.length(); i++) {
JSONObject provinceObj = data.getJSONObject(i);
String province = provinceObj.getString("name");//获取省份
provinceList.add(province);//存入省份list里面
JSONArray citys = provinceObj.getJSONArray("citys");
List<String> cityList = new ArrayList<String>();// 相应的城市列表
for (int j = 0; j < citys.length(); j++) {
JSONObject cityObj = citys.getJSONObject(j);
Iterator<String> keys = cityObj.keys();
while(keys.hasNext()){//遍历城市列表
String key = keys.next();
String city = cityObj.getString(key);
cityList.add(city);//存入城市list
codeMap.put(city, key);//存入一个城市为key,code为value的hashmap,这样可以通过城市获取code或者通过code获取城市
}
if (j == citys.length()-1) {
cityMap.put(province, cityList);//如果这个省的城市列表解析完成,就放入到一个省份为key,城市列表为value的hashmap中
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return provinceList;
}
展示时,先通过getProvinceList获取省份列表,通过listview展示,当用户点击某个省份的时候,判断是否是直辖市,如果是直辖市或者只有一个城市,则直接返回,如果有一个以上城市,则通过下面代码获取城市列表展示:
public List<String> getCityList(String province) {
return cityMap.get(province);
}
用户选择后,返回数据需要加上code,获取code函数:
public String getCode(String city){
return codeMap.get(city);
}
这样,在开始选择地区的那个activity通过onActivityResult接收选择的地区数据就可以了。
这里用code的原因是因为需要统一地区,例如,如果有几个终端来输入西藏,有些可能输入西藏自治区等,这样数据就不统一了,所以用code来统一数据很方便。
前端从后端接收地区时也是通过code来辨别,那么怎样把code解析成地址呢?
先通过code 获取city:
public String getCity(String code){
getProvinceList() ;
String city = (String)keyString(codeMap, code);
return city;
}
再通过city获取province(省份):
public String getProvince(String city){
Iterator<String> it= cityMap.keySet().iterator();
while(it.hasNext()){
String province = it.next();
List<String> cityList = cityMap.get(province);
for (int i = 0; i < cityList.size(); i++) {
if (cityList.get(i).equals(city)) {
return province;
}
}
}
return null;
}
至此组件完成,主界面如图: