在这一节的例子当中,我们做了一个非常简便的日记本程序,虽然没有完善,但是已经是基本可以使用了。在例子当中,我们不但要对数据库进行增、删、改、查的操作,而且还要把数据库当中的数据显示在一个ListView当中,通过对ListView的操作,实现对数据的增、删、改、查操作。
通过这个例子我们可以学到以下操作:
如何对DatabaseHelper和SQLiteDatabase封装,以便让我们访问数据库更加方便和安全;
如何利用ContentValues类来代替原始的SQL语句进行数据库的操作;
如何使用SimpleCursorAdapter类和ListView配合进行ListView的显示。
日记本具体实现步骤如下所述。
1.第一步
在Eclipse中打开ex08_2_SQLite 项目,具体操作步骤如下。
新建一个项目。单击File→New→Android Project项。
在新建项目的对话框中,选择Create project from existing source项。
单击浏览,找到ex08_2_SQLite项目,然后单击确定。
程序的目录结构如图8-16所示。
2.第二步
我们首先运行一下建立的程序,将会出现如图8-17所示。
(点击查看大图)图8-16 程序的目录结构 (点击查看大图)图8-17 没有任何数据的程序主界面
程序的主Activity是ActivityMain,它是一个ListActivity,和它关联的布局文件是diary_list.xml。关于ListActivity的介绍。请参阅第7章关于ListView的介绍。
3.第三步
在继续操作前,让我们重点关注一下DiaryDbAdapter类,这个类封装了DatabaseHelper和SQLiteDatabase类,使得我们对数据库的操作更加安全和方便。
在DiaryDbAdapter的类变量里,主要定义了以下几个变量:
数据库、数据表、数据表中列的名字;
DatabaseHelper 和SQLiteDatabase的实例;
Context 实例。
DatabaseHelper类的定义和上一个例子一样,只不过这个例子里边,我们在onUpgrade增加了升级的代码,具体如下所示:
代码解释:
在DiaryDbAdapter类里,向外界提供了以下一些方法。
open(),调用这个方法后,如果数据库还没有建立,那么会建立数据库,如果数据库已经建立了,那么会返回可写的数据库实例。
close(),调用此方法,DatabaseHelper 会关闭对数据库的访问。
createDiary(String title, Stringbody)通过一个title和body字段在数据库当中创建一条新的纪录。
deleteDiary(long rowId)通过记录的id,删除数据库中的那条记录。
getAllNotes()得到diary表中所有的记录,并且以一个Cursor的形式进行返回。
getDiary(long rowId)通过记录的主键id,得到特定的一条记录。
updateDiary(long rowId, String title, Stringbody)更新主键id为rowId那条记录中的两个字段title和body字段的内容。
小知识 什么是ContentValues类?
ContentValues类和Hashtable比较类似,它也是负责存储一些名值对,但是它存储的名值对当中的名是一个String类型,而值都是基本类型。
我们回顾一下,在上一个例子当中,我们是通过SQL语句进行插入操作,SQL语句的好处是比较直观,但是容易出错。但是在这个例子当中我们有更好的办法,在这里我们将要插入的值都放到一个ContentValues的实例当中,然后执行插入操作,具体代码如下所示:
代码解释:
ContentValues initialValues = newContentValues()语句实例化一个contentValues类。
initialValues.put(KEY_TITLE,title)语句将列名和对应的列值放置到initialValues里边。
mDb.insert(DATABASE_TABLE, null,initialValues)语句负责插入一条新的纪录,如果插入成功则会返回这条记录的id,如果插入失败会返回-1。
在更新一条记录的时候,我们也是采用ContentValues 的这套机制,具体代码如下所示:
代码解释:
实现更新一条记录。
4.第四步
现在返回到程序的主界面,对应的Activity是ActivityMain。
当我们单击menu按钮后会出现如图8-18所示界面。
根据我们第7章对menu的学习,对单击menu里边按钮的处理逻辑全部放在onMenuItemSelected函数里,具体代码如下所示:
代码解释:
如果单击添加一篇新日记按钮那么会执行到createDiary()语句。
如果单击删除一条记录,会执行mDbHelper.deleteDiary(getListView().getSelectedItemId())语句,首先删除当前被选中的某一项所对应的数据库当中的记录。
renderListView()语句重新对界面刷新。
在createDiary()函数里边的代码如下所示:
代码解释:
首先构造了一个intent,这个intent负责跳转到ActivityDiaryEdit里。
然后启动这个intent,并且需要返回值。
5.第五步
在ActivityMain中,有多处地方都用到了renderListView()函数。在onCreate里边用这个函数显示ListView。当ListView需要发生变化后,例如,删除了一条记录或者增加了一条记录的时候,我们调用这个函数进行刷新ListView,下边来看一下此函数的实现,具体代码如下所示:
代码解释:
mDiaryCursor =mDbHelper.getAllNotes()语句,我们首先获取数据库当中的所有数据,这些数据以Cursor的形式存在。
startManagingCursor(mDiaryCursor)语句,我们将生成的Cursor交给Activity来管理,这样的好处是系统能自动做很多事情,比如当程序暂停的时候,这个系统可以卸载Cursor以节省空间,当程序重新启动的时候系统重新查询生成Cursor。
String[] from 里边定义了ListView每一排对应的数据是从数据库中的哪个列表里选取。
和SimpleAdapter类似 int[] to里边是一个View的数组。这些View只能是TextView或者ImageView。这些View是以id的形式来表示的,如Android.R.id.text1。
SimpleCursorAdapter notes = newSimpleCursorAdapter(this,R.layout.diary_row, mDiaryCursor, from,to)语句生成一个SimpleCursorAdapter ,我们介绍以下每一个参数的意义。
第一个参数是Context。
第二个参数为R.layout.diary_row,它关联在diary_row.xml文件当中定义的Layout,这个Layout规定ListView当中每一项的布局。
第三个参数就是Cursor。
第四个参数是数据表当中的列的数组,只有在这里边出现的列名,数据才会对应的填充在to里边对应的TextView或者ImageView当中。
第五个参数是在ListView里边每一项中需要被数据填充的TextView或者ImageView。
setListAdapter(notes)语句将SimpleCursorAdapter和ListActivity里边的ListView绑定起来,至此在界面当中才会显示出列表来。
小知识 什么是SimpleCursorAdapter ?
在第7章,我们已经介绍过了ArrayAdapter和SimpleAdapter。和它们俩类似,SimpleCursorAdapter也是集成Adapter。ArrayAdapter负责把一个字符串数组中的数据填充到一个ListView当中,而对应的SimpleCursorAdapter负责把Cursor里边的内容填充到ListView当中。通过SimpleCursorAdapter可以把数据库当中一列的数据和ListView中一排进行对应起来。和前两个Adapter类似,要求和数据进行对应的View必须是TextView或者ImageView。
6.第六步
单击添加一条数据的按钮,程序运行界面如图8-19所示。
这个界面对应的Activity是ActivityDiaryEdit,对应的布局文件是diary_edit.xml。对于这个布局文件里边用到了LinearLayout、TextView和EditText,这些我们都已经讲过,在这里不再赘述,具体看一下代码: