上一篇说到将天气数据存储到了数据库中,那么我们怎么将数据库中的数据展示到界面上呢,首先,我们要将数据库导入项目中。
新建assets目录,将.db数据库文件放到该目录下,然后在MainActivity.java中将数据库导入。
/**
* 将assets目录下的文件拷贝到sd上
*
* @return 存储数据库的地址
*/
// 复制和加载区域数据库中的数据
public String copySqliteFileFromAssetsToDatabases(String SqliteFileName) {
// 第一次运行应用程序时,加载数据库到data/data/当前包的名称/database/
File dir = new File("data/data/" + getPackageName() + "/databases");
//判断如果文件夹不存在,或者不是一个目录,那么就创建一个文件夹
if (!dir.exists() || !dir.isDirectory()) {
dir.mkdir();
}
//获取file对象
File file = new File(dir, SqliteFileName);
InputStream inputStream = null;
OutputStream outputStream = null;
//通过IO流的方式,将assets目录下的数据库文件,写入到SD卡中。
if (!file.exists()) {
try {
file.createNewFile();
inputStream = getClass().getClassLoader().getResourceAsStream("assets/" + SqliteFileName);
outputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return file.getPath();
}
然后,新建一个类,专门用来对数据库信息进行操作。
获取省市县数据并返回一个集合。
/**
* 从数据库中获得省份信息
*
* @return 省市县信息集合
*/
public List getProvincesFromSQLite(String sqlPath) {
SQLiteDatabase db = SQLiteDatabase.openDatabase(sqlPath, null, SQLiteDatabase.OPEN_READONLY);
List provinceList = new ArrayList<>();
if (provinceList.size() == 0) {
Cursor cursor = db.rawQuery("select * from tb_province", null);
provinceList.clear();
//查询省份信息
if (cursor.moveToFirst()) {
do {
Province province = new Province();
province.id = cursor.getInt(cursor.getColumnIndex("id"));
province.provinceName = cursor.getString(cursor.getColumnIndex("province_name"));
// Log.d("sqlprovince_", province.provinceName);
provinceList.add(province);
} while (cursor.moveToNext());
}
//查询城市信息
for (int i = 0; i < provinceList.size(); i++) {
List cityList = new ArrayList();
cursor = db.query("tb_city", new String[]{"id", "city_name"}, "province_id=?", new String[]{provinceList.get(i).id + ""}, null, null, null);
// Log.d("test__", cursor.getCount() + "");
// Log.d("test__", "test" + i);
if (cursor.moveToFirst()) {
do {
City city = new City();
city.id = cursor.getInt(cursor.getColumnIndex("id"));
city.cityName = cursor.getString(cursor.getColumnIndex("city_name"));
cityList.add(city);
// Log.d("sqlcity_", city.cityName);
} while (cursor.moveToNext());
}
provinceList.get(i).cityList = cityList;
//查询县城信息
for (int j = 0; j < cityList.size(); j++) {
List countyList = new ArrayList();
cursor = db.query("tb_county", new String[]{"county_name"}, "city_id=?", new String[]{cityList.get(j).id + ""}, null, null, null);
if (cursor.moveToFirst()) {
do {
County county = new County();
county.countyName = cursor.getString(cursor.getColumnIndex("county_name"));
countyList.add(county);
// Log.d("sqlcounty_", county.countyName);
} while (cursor.moveToNext());
}
cityList.get(j).countyList = countyList;
}
}
cursor.close();
}
db.close();
return provinceList;
}
获取了数据,接下啦我们需要一个承载数据的控件,在这里我选择使用DrawerLayout控件来展示数据。首先,在布局文件中,引入DrawerLayout控件。在该控件内加入ExpandableListView来展示省市县数据。
activity_main.xml
.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawerlayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
"wrap_content"
android:layout_height="wrap_content">
.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/load">
.support.v4.view.ViewPager>
"@+id/layout_locate"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/textColor">
"300dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="@color/textColor"
android:orientation="vertical">
"@+id/expandable_drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:headerDividersEnabled="true">
.support.v4.widget.DrawerLayout>
接下来,对该侧滑菜单进行初始化。
/**
* 初始化侧滑菜单
*/
private void initDrawer() {
//获得侧滑菜单控件
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerlayout);
//为侧滑菜单添加监听事件
mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
//获得actionbar的布局
View view = actionBar.getCustomView();
//获得城市管理和城市添加控件
ImageView imgCityManager = view.findViewById(R.id.img_city_manage);
ImageView imgCityAdd = view.findViewById(R.id.img_city_add);
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
}
@Override
public void onDrawerOpened(View drawerView) {
//当侧滑菜单打开时,将添加图标设为可见
imgCityAdd.setVisibility(View.VISIBLE);
//将城市管理图标设为不可见
imgCityManager.setVisibility(View.INVISIBLE);
}
@Override
public void onDrawerClosed(View drawerView) {
//当侧滑菜单关闭时,将城市管理图标设为可见
imgCityManager.setVisibility(View.VISIBLE);
//将添加图标设为不可见
imgCityAdd.setVisibility(View.INVISIBLE);
if (mCityNameList.size() != 0) {
//获取actionBar中的标题控件
TextView tvTitle = actionBar.getCustomView().findViewById(R.id.title);
//获取当前viewpager的view索引
int viewIndex = viewPager.getCurrentItem();
//通过索引为title设置城市名称
tvTitle.setText(viewIndex >= 0 ? mCityNameList.get(viewIndex) : "");
}
}
@Override
public void onDrawerStateChanged(int newState) {
}
});
//从数据库中获得城市数据并将其放入侧滑菜单中
//获取省份列表集合
List provinceList = new SQLiteInfo().getProvincesFromSQLite(sqlPath);
//获取expandableDrawer的控件
ExpandableListView expandableDrawer = (ExpandableListView) findViewById(R.id.expandable_drawer);
//为该控件设置adapter
expandableDrawer.setAdapter(new MySecondExpandableListAdapter(this, provinceList));
// Log.d("provinceList_", provinceList.size() + "");
}
其中使用ExpandableListView实现了三级列表,实现原理为:在一级的子项中再包一个ExpandableListView即可。下面是实现过程:
/**
* Created by zhaoxin on 17/9/7.
* 设置一级目录的适配器,在子列表项中再设置一个ExpandableView,用来显示三级目录
*/
public class MySecondExpandableListAdapter extends BaseExpandableListAdapter {
//存储省份的集合
private List mProvinces;
//上下文
private Context mContext;
//通过构造器初始化成员变量
public MySecondExpandableListAdapter(Context context, List provinces) {
this.mContext = context;
this.mProvinces = provinces;
}
@Override
public int getGroupCount() {
return mProvinces.size();
}
@Override
public int getChildrenCount(int i) {
return 1;
}
@Override
public Object getGroup(int i) {
return mProvinces.get(i);
}
@Override
public Object getChild(int i, int i1) {
return mProvinces.get(i).cityList.get(i1);
}
@Override
public long getGroupId(int i) {
return i;
}
@Override
public long getChildId(int i, int i1) {
return i1;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
TextView tvProvince;
if (view == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.item_province, null);
tvProvince = view.findViewById(R.id.tv_province);
viewHolder = new ViewHolder(tvProvince);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
tvProvince = viewHolder.mTextView;
}
tvProvince.setText(mProvinces.get(i).provinceName);
return view;
}
@Override
public View getChildView(final int i, int i1, boolean b, View view, ViewGroup viewGroup) {
//解决显示不全的问题
CustomExpandableListView customExpandableListView = new CustomExpandableListView(mContext);
//在一级目录的子目录中设置二级目录
MyExpandableListAdapter myExpandableListAdapter = new MyExpandableListAdapter(mContext, mProvinces.get(i).cityList);
customExpandableListView.setAdapter(myExpandableListAdapter);
//三级目录 县级点击事件
customExpandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView expandableListView, View view, int j, int k, long l) {
View v = MainActivity.actionBar.getCustomView();
TextView textView = v.findViewById(R.id.title);
textView.setText(mProvinces.get(i).cityList.get(j).countyList.get(k).countyName);
Log.d("textView_", textView.getText().toString());
return false;
}
});
return customExpandableListView;
}
@Override
public boolean isChildSelectable(int i, int i1) {
return true;
}
//解决显示不全的问题
class CustomExpandableListView extends ExpandableListView {
public CustomExpandableListView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//解决显示不全的问题
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2
, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
private class ViewHolder {
private TextView mTextView;
ViewHolder(TextView textView) {
this.mTextView = textView;
}
}
}
/**
* Created by zhaoxin on 17/9/6.
* 设置二级目录的适配器
*/
class MyExpandableListAdapter extends BaseExpandableListAdapter {
//存储城市的集合
private List mCities;
//上下文
private Context mContext;
//通过构造器初始化成员变量
MyExpandableListAdapter(Context context, List mCities) {
this.mContext = context;
this.mCities = mCities;
}
//组列表项的个数
@Override
public int getGroupCount() {
return mCities.size();
}
//子列表项的个数
@Override
public int getChildrenCount(int i) {
return mCities.get(i).countyList.size();
}
//获取指定组位置处的组数据
@Override
public Object getGroup(int i) {
return mCities.get(i);
}
//获取指定组位置、子列表项处的子列表项数据
@Override
public Object getChild(int i, int i1) {
return mCities.get(i).countyList.get(i1);
}
//获取组列表项的id
@Override
public long getGroupId(int i) {
return i;
}
//获取子列表项的id
@Override
public long getChildId(int i, int i1) {
return i1;
}
@Override
public boolean hasStableIds() {
return false;
}
//返回的view对象作为组列表项
@Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
TextView tvCity;
if (view == null) {
//加载显示城市列表布局
view = LayoutInflater.from(mContext).inflate(R.layout.item_city, null);
//获取显示城市的控件
tvCity = view.findViewById(R.id.tv_city);
viewHolder = new ViewHolder(tvCity);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
tvCity = viewHolder.mTextView;
}
tvCity.setText(mCities.get(i).cityName);
return view;
}
//返回的view对象作为特定组、特定位置的子列表项
@Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
TextView tvCounty;
if (view == null) {
view = LayoutInflater.from(mContext).inflate(R.layout.item_county, null);
tvCounty = view.findViewById(R.id.tv_county);
viewHolder = new ViewHolder(tvCounty);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) view.getTag();
tvCounty = viewHolder.mTextView;
}
tvCounty.setText(mCities.get(i).countyList.get(i1).countyName);
return view;
}
@Override
public boolean isChildSelectable(int i, int i1) {
return true;
}
private class ViewHolder {
private TextView mTextView;
ViewHolder(TextView textView) {
this.mTextView = textView;
}
}
}
至此,就实现了城市数据的展示。