背景
最近因为业务需要,要实现选择到区县的功能,以前的常用数据库并不包含区县数据,所以自己特地到网上寻找包含区县数据的数据库文件。
本来想用常规读取SQLite的方式呈现数据,但是刚好浏览到json格式的数据,突发奇想,能不能用json数据来作为数据源呢?
说干就干,尝试了一番之后,终于把效果实现出来了,还是比较满意的。下面是效果图:
废话不多说,接下来说说如何实现的思路。
代码实现
我是用三个并排的listview,往里面填充区域数据的,这是主界面的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/lv_pro"
android:layout_width="110dp"
android:layout_height="wrap_content" />
<ListView
android:id="@+id/lv_city"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/lv_pro" />
<ListView
android:id="@+id/lv_dis"
android:layout_width="110dp"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/lv_city" />
</RelativeLayout>
说到这里,还有一点郁闷的地方,本来我是打算使用RecyclerView的,但是不知何故,并排放置三个RecyclerView,设置好设配器的时候,前面的RecyclerView无法显示出来了,很是郁闷。在此,如果有知道解决办法的童鞋,还望赐教一二。
界面弄完之后,接下来就写功能代码了,具体的实现如下:
package cn.zhuziyu.selectarea;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnItemClick;
import cn.zhuziyu.selectarea.model.CityData;
import cn.zhuziyu.selectarea.model.DistrictData;
import cn.zhuziyu.selectarea.model.ProvinceData;
/**
* @author Zen
* @date 2016/3/27 0027 15:05
*/
public class AreaActivity extends AppCompatActivity {
@Bind(R.id.lv_city)
ListView lvCity;
@Bind(R.id.lv_pro)
ListView lvPro;
@Bind(R.id.lv_dis)
ListView lvDis;
private InputStreamReader reader;
private Gson gson;
private List<ProvinceData> proData;
private List<CityData> cityData, cityCheckData; //前者放置所有的城市数据,后者放置根据条件选择的城市数据
private List<DistrictData> disData, disCheckData;//同上
private List<String> proDatas;
private List<String> cityDatas;
private List<String> disDatas;
private ArrayAdapter<String> cityAdapter, disAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_area);
ButterKnife.bind(this);
gson = new Gson();
initView();
}
protected void initView() {
//刚进来的时候,立刻给省的ListView填充数据
try {
Type proType = new TypeToken<ArrayList<ProvinceData>>() {
}.getType();
proData = getLocData("ProvinceData.json", proType);
proDatas = new ArrayList<>();
for (ProvinceData data : proData) {
proDatas.add(data.getName());
}
lvPro.setAdapter(new ArrayAdapter<>(AreaActivity.this, android.R.layout.simple_list_item_1, proDatas));
} catch (IOException e) {
e.printStackTrace();
}
//初始化另外两个ListView
cityData = new ArrayList<>();
cityDatas = new ArrayList<>();
cityCheckData = new ArrayList<>();
cityAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, cityDatas);
lvCity.setAdapter(cityAdapter);
disData = new ArrayList<>();
disDatas = new ArrayList<>();
disCheckData = new ArrayList<>();
disAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, disDatas);
lvDis.setAdapter(disAdapter);
}
/**
* 省Listview的item点击事件
*
* @param position
*/
@OnItemClick(R.id.lv_pro)
void selectPro(int position) {
Log.i("TAG", "Position:" + position);
cityData.clear();//添加数据前,先删除旧数据
cityDatas.clear();
cityCheckData.clear();
disDatas.clear(); //清除区的数据列表,并通知区更新数据
disData.clear();
disCheckData.clear();
disAdapter.notifyDataSetChanged();
try {
int proId = proData.get(position).getProID(); //proId
Type cityType = new TypeToken<ArrayList<CityData>>() {
}.getType();
cityData = getLocData("CityData.json", cityType);
for (CityData data : cityData) {
if (data.getProID() == proId) { //根据proId,查找名下的城市
cityDatas.add(data.getName());
cityCheckData.add(data);
}
}
cityAdapter.notifyDataSetChanged(); //通知listView更新数据
} catch (IOException e) {
e.printStackTrace();
}
}
@OnItemClick(R.id.lv_city)
void selectCity(int position) {
Log.i("TAG", "Position:" + position);
disDatas.clear();
disData.clear();
disCheckData.clear();
try {
int cityId = cityCheckData.get(position).getCityID();
Log.i("TAG", "cityId:" + cityId);
Type disType = new TypeToken<ArrayList<DistrictData>>() {
}.getType();
disData = getLocData("DistrictData.json", disType);
for (DistrictData data : disData) {
if (data.getCityID() == cityId) {
disDatas.add(data.getDisName());
disCheckData.add(data);
}
}
disAdapter.notifyDataSetChanged();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);
}
/**
* 泛型方法,读取assets目录下的json文件,并填充到List中
*
* @param fileName
* @param collectionType
* @param <T>
* @return
* @throws IOException
*/
public <T> List<T> getLocData(String fileName, Type collectionType) throws IOException {
//获取assets目录下的json文件
reader = new InputStreamReader(getAssets().open(fileName));
List<T> locDatas = gson.fromJson(reader, collectionType);
reader.close();
return locDatas;
}
}
整个实现过程就是这样子了,整个代码还有优化空间,不过迫于时间,就先这样了,等我有空了,在来优化一下代码,提升整体的读取性能。
工程已经放在Github上了,欢迎各位点评: 点我