一个三级联动的问题,需求原型图上是一个spnner效果,本来想用pop+listview的,但是手一哆嗦就写了三个spnner,然后就用spnner做了,后台哥们想给我传json数据把城市信息给我呢,由于数据太多,我就直接用Navicat 数据库管理将php给的.sql数据库文件转成了.db格式的,然后导入assets文件夹里,下面开始解析出来数据库的各种子id,父id,城市名,不多说了,上代码吧:
/** * 城市数据库读取 */ private void cityDao() { //数据库操作 //打开数据库输出流 SQLdm s = new SQLdm(); SQLiteDatabase db = s.openDatabase(getApplicationContext()); //找到每个省 然后根据area_parent_id找到每个省对应的市 //把市添加到省集合中 再找到每个市 根据area_parent_id找到每个市对应的区 //把区添加到市集合中 //省集合 province_list = new ArrayList<>(); //找到每个省 Cursor cursor = db.rawQuery("select * from pst_area where area_deep=?", new String[]{"1"}); while (cursor.moveToNext()) { String area_id1 = cursor.getString(cursor.getColumnIndex("area_id")); //省id String name1 = cursor.getString(cursor.getColumnIndex("area_name")); String area_parent_id1 = cursor.getString(cursor.getColumnIndex("area_parent_id")); //父id 此处没有 String area_deep1 = cursor.getString(cursor.getColumnIndex("area_deep")); //一级 city_list = new ArrayList<>(); //找到每个省对应的市 当area_parent_id==area_id 条件查询 Cursor cursorr = db.rawQuery("select * from pst_area where area_parent_id=?", new String[]{area_id1}); while (cursorr.moveToNext()) { String area_id2 = cursorr.getString(cursorr.getColumnIndex("area_id")); //市id String name2 = cursorr.getString(cursorr.getColumnIndex("area_name")); String area_parent_id2 = cursorr.getString(cursorr.getColumnIndex("area_parent_id")); //父id 此处没有 String area_deep2 = cursorr.getString(cursorr.getColumnIndex("area_deep")); //二级 district_list = new ArrayList<>(); //找到每个省对应的区 当area_parent_id==area_id 条件查询 Cursor cursorrq = db.rawQuery("select * from pst_area where area_parent_id=?", new String[]{area_id2}); while (cursorrq.moveToNext()) { String area_id3 = cursorrq.getString(cursorrq.getColumnIndex("area_id")); //区id String name3 = cursorrq.getString(cursorrq.getColumnIndex("area_name")); String area_parent_id3 = cursorrq.getString(cursorrq.getColumnIndex("area_parent_id")); //父id 此处没有 String area_deep3 = cursorrq.getString(cursorrq.getColumnIndex("area_deep")); //三级 //添加至区集合 District district = new District(); //区对象 district.setArea_id(area_id3); district.setArea_name(name3); district.setArea_deep(area_deep3); district.setArea_parent_id(area_parent_id3); district_list.add(district); } //添加至市集合 City city = new City(); //市对象 city.setDistricts(district_list); city.setArea_id(area_id2); city.setArea_name(name2); city.setArea_deep(area_deep2); city.setArea_parent_id(area_parent_id2); city_list.add(city); } //添加至省集合 Province province = new Province(); //省对象 province.setCitys(city_list); province.setArea_id(area_id1); province.setArea_name(name1); province.setArea_deep(area_deep1); province.setArea_parent_id(area_parent_id1); province_list.add(province); } //将集合用sp保存起来 address_sp.setDataList("address_tag", province_list);
这种古老的查询方法确实很锻炼人,保存起来后,紧接着设置设配器和监听:
private void init(int Province_id,int City_id,int Districte_id) { arrayAdapter1 = new ArrayAdapter<Province>(AddAddressActivity.this, R.layout.support_simple_spinner_dropdown_item, province_list); arrayAdapter2 = new ArrayAdapter<City>(AddAddressActivity.this, R.layout.support_simple_spinner_dropdown_item, province_list.get(Province_id).getCitys()); arrayAdapter3 = new ArrayAdapter<District>(AddAddressActivity.this, R.layout.support_simple_spinner_dropdown_item, province_list.get(Province_id).getCitys().get(City_id).getDistricts()); province_sn.setAdapter(arrayAdapter1); city_sn.setAdapter(arrayAdapter2); county_sn.setAdapter(arrayAdapter3); province_sn.setSelection(Province_id, true); city_sn.setSelection(City_id, true); county_sn.setSelection(Districte_id, true); //省 province_sn.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { AddAddressActivity.this.province = province_list.get(position); arrayAdapter2 = new ArrayAdapter<City>(AddAddressActivity.this, R.layout.support_simple_spinner_dropdown_item, province_list.get(position).getCitys()); city_sn.setAdapter(arrayAdapter2); province_postion = position; province_area_name_select = province_list.get(position).getArea_name(); province_area_id_select = province_list.get(position).getArea_id(); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); //市 city_sn.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { arrayAdapter3 = new ArrayAdapter<District>(AddAddressActivity.this, R.layout.support_simple_spinner_dropdown_item, AddAddressActivity.this.province.getCitys().get(position).getDistricts()); county_sn.setAdapter(arrayAdapter3); city_postion = position; city_area_name_select = province_list.get(province_postion).getCitys().get(position).getArea_name(); city_area_id_select = province_list.get(province_postion).getCitys().get(position).getArea_id(); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); //区 county_sn.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> adapterView, View view, int position, long l) { county_postion = position; county_area_name_select = province_list.get(province_postion).getCitys().get(city_postion).getDistricts().get(position).getArea_name(); county_area_id_select = province_list.get(province_postion).getCitys().get(city_postion).getDistricts().get(position).getArea_id(); } @Override public void onNothingSelected(AdapterView<?> adapterView) { } }); }
我在想这个spnner不能直接将文字设置上去,而是要通过索引,也就是province_sn.setSelection(1, true);方法给设置上去,所以设置上去之前就必须给它先设置好数据源,那么我就开始想办法,既然集合已经保存了,后台也会返回回显的城市名字,我就直接在集合里遍历循环开始找对应的key吧,代码走着:
/** * 回显地址信息 * * @param province_id * @param city_id * @param country_id */ private void showLocation(String province_id, String city_id, String country_id) { for (int i = 0; i < province_list.size(); i++) { if (province_id.equals(province_list.get(i).getArea_id())) { province_sn.setSelection(i, true); for (int j = 0; j < province_list.get(i).getCitys().size(); j++) { if (city_id.equals(province_list.get(i).getCitys().get(j).getArea_id())) { city_sn.setSelection(j, true); for (int k = 0; k < province_list.get(i).getCitys().get(j).getDistricts().size(); k++) { if (country_id.equals(province_list.get(i).getCitys().get(j).getDistricts().get(k).getArea_id())) { county_sn.setSelection(k, true); } } } } } } }
当时写完这段,感觉做为一个前端好累啊,还要这么查,运行后发现这段代码并什么卵用,根本定位不到,果断就找后台去了,让后台哥们给我加了三个城市分别对应的选中的索引值字段,新字段来了,操练起来了,结果设置各种后发现只有省级是可以定位到的,市级,区级只是数据显示了,却索引位始终是0位置,并没有定位到,当时的代码:
arrayAdapter1 = new ArrayAdapter<Province>(AddAddressActivity.this, R.layout.support_simple_spinner_dropdown_item, province_list); arrayAdapter2 = new ArrayAdapter<City>(AddAddressActivity.this, R.layout.support_simple_spinner_dropdown_item, province_list.get(Province_id).getCitys()); arrayAdapter3 = new ArrayAdapter<District>(AddAddressActivity.this, R.layout.support_simple_spinner_dropdown_item, province_list.get(Province_id).getCitys().get(City_id).getDistricts()); province_sn.setAdapter(arrayAdapter1); city_sn.setAdapter(arrayAdapter2); county_sn.setAdapter(arrayAdapter3); province_sn.setSelection(Province_id, true); city_sn.setSelection(City_id, true); county_sn.setSelection(Districte_id, true);
左思右想代码,没问题,肯定可以的啊,项目也很紧张,各种资料翻spnner的属性和特点,查到一篇帖子是这样说的,setSelection(Province_id, true);二参如果为ture的话,会自动刷新,而且会重新走一遍
setOnItemSelectedListener监听,这时我一看setOnItemSelectedListener下的代码:
//省 province_sn.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { AddAddressActivity.this.province = province_list.get(position); arrayAdapter2 = new ArrayAdapter<City>(AddAddressActivity.this, R.layout.support_simple_spinner_dropdown_item, province_list.get(position).getCitys()); city_sn.setAdapter(arrayAdapter2); province_postion = position; province_area_name_select = province_list.get(position).getArea_name(); }里面竟然又走了一遍设置市级的数据,这下就有谱了,本来是定位到的,结果市级区级又重新设置了一遍适配器,所以给人感觉就是没定位到。
后来解决办法也很简单,在onItemSelected方法里直接加了个判断,如果是回显的情况下就直接返回:
if (address_id != null) { return; }问题解决,怪自己对控件的属性了解不彻底,但是财富值+1,那是没得说的。希望对大家有帮助。