- 浏览: 240456 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
xchd:
分别在什么时候(情况下)用ThreadFactory、Exec ...
Executor线程池实例 -
mikey_5:
是不是没有写完啊
Executor线程池实例 -
xinyao:
楼主,你好,请问能给我发个源码吗,我要在一个页面能实时看到下载 ...
Android学习系列(19)--App离线下载 -
sdtzkj:
...
jasperReport 帮助文档 api -
shero_ys:
public class VrowsePicActivity ...
android handler 实现三步曲
在上一个例子中,我们对Android系统自带的SQLite数据库进行了初步的学习,了解了一些增、删、改、查的基本工作。在这一节的例子当中,我们做了一个非常简便的日记本程序,虽然没有完善,但是已经是基本可以使用了。在例子当中,我们不但要对数据库进行增、删、改、查的操作,而且还要把数据库当中的数据显示在一个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增加了升级的代码,具体如下所示:
- private static class DatabaseHelper extends SQLiteOpenHelper {
- DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
- @Override
- public void onCreate(SQLiteDatabase db) {
- //生成数据库
- db.execSQL(DATABASE_CREATE);
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL("DROP TABLE IF EXISTS diary");
- onCreate(db);
- }
- }
代码解释:
在DiaryDbAdapter类里,向外界提供了以下一些方法。
open(),调用这个方法后,如果数据库还没有建立,那么会建立数据库,如果数据库已经建立了,那么会返回可写的数据库实例。
close(),调用此方法,DatabaseHelper 会关闭对数据库的访问。
createDiary(String title, String body)通过一个title和body字段在数据库当中创建一条新的纪录。
deleteDiary(long rowId)通过记录的id,删除数据库中的那条记录。
getAllNotes()得到diary表中所有的记录,并且以一个Cursor的形式进行返回。
getDiary(long rowId)通过记录的主键id,得到特定的一条记录。
updateDiary(long rowId, String title, String body)更新主键id为rowId那条记录中的两个字段title和body字段的内容。
小知识 什么是ContentValues类?
ContentValues类和Hashtable比较类似,它也是负责存储一些名值对,但是它存储的名值对当中的名是一个String类型,而值都是基本类型。
我们回顾一下,在上一个例子当中,我们是通过SQL语句进行插入操作,SQL语句的好处是比较直观,但是容易出错。但是在这个例子当中我们有更好的办法,在这里我们将要插入的值都放到一个ContentValues的实例当中,然后执行插入操作,具体代码如下所示:
- public long createDiary(String title, String body) {
- ContentValues initialValues = new ContentValues();
- initialValues.put(KEY_TITLE, title);
- initialValues.put(KEY_BODY, body);
- Calendar calendar = Calendar.getInstance();
- // 生成年月日字符串
- String created = calendar.get(Calendar.YEAR) +"年"+calendar.get(Calendar. MONTH)+"月"+calendar.get (Calendar.DAY_OF_MONTH)+"日"+calendar.get(Calendar. HOUR_OF _DAY)+"时"+calendar.get(Calendar.MINUTE)+"分";
- initialValues.put(KEY_CREATED, created);
- return mDb.insert(DATABASE_TABLE, null, initialValues);
- }
代码解释:
ContentValues initialValues = new ContentValues()语句实例化一个contentValues类。
initialValues.put(KEY_TITLE, title)语句将列名和对应的列值放置到initialValues里边。
mDb.insert(DATABASE_TABLE, null, initialValues)语句负责插入一条新的纪录,如果插入成功则会返回这条记录的id,如果插入失败会返回-1。
在更新一条记录的时候,我们也是采用ContentValues 的这套机制,具体代码如下所示:
- public boolean updateDiary(long rowId, String title, String body) {
- ContentValues args = new ContentValues();
- args.put(KEY_TITLE, title);
- args.put(KEY_BODY, body);
- Calendar calendar = Calendar.getInstance();
- String created = calendar.get(Calendar.YEAR) + "年"
- + calendar.get(Calendar.MONTH) + "月"
- + calendar.get(Calendar.DAY_OF_MONTH) + "日"
- + calendar.get(Calendar.HOUR_OF_DAY) + "时"
- + calendar.get(Calendar.MINUTE) + "分";
- args.put(KEY_CREATED, created);
- return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
- }
代码解释:
实现更新一条记录。
4.第四步
现在返回到程序的主界面,对应的Activity是ActivityMain。
当我们单击menu按钮后会出现如图8-18所示界面。
(点击查看大图)图8-18 单击menu
根据我们第7章对menu的学习,对单击menu里边按钮的处理逻辑全部放在onMenuItem Selected函数里,具体代码如下所示:
- public boolean onMenuItemSelected(int featureId, MenuItem item) {
- switch (item.getItemId()) {
- case INSERT_ID:
- createDiary();
- return true;
- case DELETE_ID:
- mDbHelper.deleteDiary(getListView().getSelectedItemId());
- renderListView();
- return true;
- }
- return super.onMenuItemSelected(featureId, item);
- }
代码解释:
如果单击添加一篇新日记按钮那么会执行到createDiary()语句。
如果单击删除一条记录,会执行mDbHelper.deleteDiary(getListView().getSelectedItemId())语句,首先删除当前被选中的某一项所对应的数据库当中的记录。
renderListView()语句重新对界面刷新。
在createDiary()函数里边的代码如下所示:
- private void createDiary() {
- Intent i = new Intent(this, ActivityDiaryEdit.class);
- startActivityForResult(i, ACTIVITY_CREATE);
- }
代码解释:
首先构造了一个intent,这个intent负责跳转到ActivityDiaryEdit里。
然后启动这个intent,并且需要返回值。
5.第五步
在ActivityMain中,有多处地方都用到了renderListView()函数。在onCreate里边用这个函数显示ListView。当ListView需要发生变化后,例如,删除了一条记录或者增加了一条记录的时候,我们调用这个函数进行刷新ListView,下边来看一下此函数的实现,具体代码如下所示:
- private void renderListView() {
- mDiaryCursor = mDbHelper.getAllNotes();
- startManagingCursor(mDiaryCursor);
- String[] from = new String[] { DiaryDbAdapter.KEY_TITLE,
- DiaryDbAdapter.KEY_CREATED };
- int[] to = new int[] { R.id.text1, R.id.created };
- SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
- R.layout.diary_row, mDiaryCursor, from, to);
- setListAdapter(notes);
- }
代码解释:
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 = new SimpleCursorAdapter(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所示。
(点击查看大图)图8-19 新建一篇日记的界面
这个界面对应的Activity是ActivityDiaryEdit,对应的布局文件是diary_edit.xml。对于这个布局文件里边用到了LinearLayout、TextView和EditText,这些我们都已经讲过,在这里不再赘述,具体看一下代码:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
- Android:orientation="vertical" Android:layout_width="fill_parent"
- Android:layout_height="fill_parent">
- <LinearLayout Android:orientation="vertical"
- Android:layout_width="fill_parent"
- Android:layout_height="wrap_content">
- <TextView Android:layout_width="wrap_content"
- Android:layout_height="wrap_content" Android:text="@string/title"
- Android:padding="2px" />
- <EditText Android:id="@+id/title"
- Android:layout_width="fill_parent"
- Android:layout_height="wrap_content" Android:layout_weight="1" />
- </LinearLayout>
- <TextView Android:layout_width="wrap_content"
- Android:layout_height="wrap_content" Android:text="@string/body" />
- <EditText Android:id="@+id/body" Android:layout_width="fill_parent"
- Android:layout_height="wrap_content" Android:layout_weight="1"
- Android:scrollbars="vertical" />
- <Button Android:id="@+id/confirm" Android:text="@string/confirm"
- Android:layout_width="wrap_content"
- Android:layout_height="wrap_content" />
- </LinearLayout>
代码解释:
在一个LinearLayout里边我们放置了一些文本框、输入框和一些Button按钮。
当程序运行输入内容后,单击确定按钮,日记就会保存到数据库当中。下边来看一下代码具体是怎么执行的。当单击确定按钮后,系统回调执行和按钮绑定的单击监听器里边的onClick方法,具体代码如下所示:
- public void onClick(View view) {
- String title = mTitleText.getText().toString();
- String body = mBodyText.getText().toString();
- if (mRowId != null) {
- mDbHelper.updateDiary(mRowId, title, body);
- } else
- mDbHelper.createDiary(title, body);
- Intent mIntent = new Intent();
- setResult(RESULT_OK, mIntent);
- finish();
- }
代码解释:
首先获得EditView里边的数据。
目前mRowId 为null,所以执行mDbHelper.createDiary(title, body)语句将数据保存到数据当中。
setResult(RESULT_OK, mIntent)语句设置返回值。
执行完上边的代码后,系统跳转到ActivityMain,并执行回调函数onActivityResult,具体代码如下所示:
- protected void onActivityResult(int requestCode, int resultCode,
- Intent intent) {
- super.onActivityResult(requestCode, resultCode, intent);
- renderListView();
- }
代码解释:
在回调函数中,我们重新对ListView进行刷新,将所有的数据重新显示出。
7.第七步
单击ListView里边的条列,可以对刚才保存的数据进行编辑。具体怎么实现这个功能的,我们可以看一下ActivityMain当中的onListItemClick方法代码:
- protected void onListItemClick(ListView l, View v, int position, long id) {
- super.onListItemClick(l, v, position, id);
- Cursor c = mDiaryCursor;
- c.moveToPosition(position);
- Intent i = new Intent(this, ActivityDiaryEdit.class);
- i.putExtra(DiaryDbAdapter.KEY_ROWID, id);
- i.putExtra(DiaryDbAdapter.KEY_TITLE, c.getString (c .getColumnIndexOrThrow(DiaryDbAdapter.KEY_TITLE)));
- i.putExtra(DiaryDbAdapter.KEY_BODY, c.getString (c .getColumnIndexOrThrow(DiaryDbAdapter.KEY_BODY)));
- startActivityForResult(i, ACTIVITY_EDIT);
- }
代码解释:
c.moveToPosition(position)语句将在Cursor当中的指针移到position位置,这个position是我们单击的这个一列在整个列表中的位置。
Intent i = new Intent(this, ActivityDiaryEdit.class)语句构造一个跳转到ActivityDiaryEdit的intent。
putExtra()方法负责将要传递的数据放到intent当中。
c.getString(c.getColumnIndexOrThrow(DiaryDbAdapter.KEY_TITLE))得到这一条数据中列名为title的值。
c.getString(c.getColumnIndexOrThrow(DiaryDbAdapter.KEY_BODY))得到这一条数据中列名为body的值。
startActivityForResult(i, ACTIVITY_EDIT)语句启动intent,发生Activity的跳转。
我们来看一下ActivityDiaryEdit中的onCreate()里边的代码:
- Bundle extras = getIntent().getExtras();
- if (extras != null) {
- String title = extras.getString(DiaryDbAdapter.KEY_TITLE);
- String body = extras.getString(DiaryDbAdapter.KEY_BODY);
- mRowId = extras.getLong(DiaryDbAdapter.KEY_ROWID);
- if (title != null) {
- mTitleText.setText(title);
- }
- if (body != null) {
- mBodyText.setText(body);
- }
- }
代码解释:
对于ActivityDiaryEdit这个Activity有两个intent可以跳转进来,一个是新建一篇日记的时候,这个时候intent里边的extras部分没有任何数据。第二种情况是在单击列表的某一个条列的时候,这个时候的intent如上所示会携带extras数据。所以在ActivityDiaryEdit中我们通过判断extras是否为null,就可以判断是哪种intent启动的。
当extras不为null,我们将extras里边的数据显示出来。
8.第八步
在程序的主界面当中,上下移动焦点(可以通过键盘的上下键或者模拟器中的上下按键),可以对拥有焦点的那一项进行删除,如图8-20、图8-21、图8-22所示。
(点击查看大图)图8-20 上下移动焦点界面 |
- mDbHelper.deleteDiary(getListView().getSelectedItemId());
- renderListView();
代码解释:
getListView()方法获取当前的ListView引用。
getSelectedItemId()方法得到当前这一列所对应的数据项的rowId,也就是这条数据在数据库中的主键id。
(点击查看大图)图8-21 进行删除界面 |
(点击查看大图)图8-22 删除后界面 |
mDbHelper.deleteDiary()方法删去数据库中的这一列数据。
renderListView()负责对列表重新刷新一遍。
至此,对数据库的学习就先告一段落,接下来将学习contentProvider,它是Android应用当中非常重要的一部分。而且程序间的大部分数据交换都是通过contentProvider机制进行。
发表评论
-
Android学习系列(19)--App离线下载
2011-08-13 11:40 1426Android学习系列(19)--App离线下载 ... -
Android学习系列(20)-App数据格式之解析Json
2011-08-13 11:28 1639JSON数据格式,在Android中被广泛运用于客户端和网络( ... -
Android学习系列(1)--为App签名(为apk签名)
2011-08-13 11:20 1693写博客是一种快乐,前提是你有所写,与人分享,是另一种快乐, ... -
Android学习系列(4)--App自适应draw9patch不失真背景
2011-08-13 11:16 2230做人要大度,海纳百川,做事要圆滑,左右逢源,这让我想到了编程也 ... -
Android自定义View之一:初探实例 .
2011-08-13 11:09 1496Android自定义View实现很简单 继承View,重写构 ... -
Android多媒体学:播放网络上的视频 .
2011-08-13 11:05 2073Android支持播放网络上的视频。在播放网络上的视频时,牵涉 ... -
Android多媒体学:利用AudioRecord类实现自己的音频录制程序 .
2011-08-13 11:02 5901AudioRecord类相对于MediaRecorder来说, ... -
Android多媒体:实现图像的编辑和合成 .
2011-08-13 10:59 2200package demo.camera; import ja ... -
自动完成框
2011-05-03 13:44 761请下载源码 -
读取sd卡照片
2011-05-03 13:43 1315请下载源码 -
UC菜单栏布局
2011-05-03 13:41 1131请下载附件 -
Executor线程池实例
2011-04-06 17:42 6709Executor 是 java5 下的一个 ... -
android handler 实现三步曲
2011-04-06 16:59 1443一. 要实现接口: public class VrowseP ... -
android 横竖屏切换
2011-03-25 14:33 1940①不理会。。②只竖屏 ... -
android 分辨率调试
2011-03-25 13:36 1874一:不同的layout Android ... -
android 图片内存溢出
2011-03-21 18:24 3106我的代码如下 is = new FileI ... -
android Exid 不可修改
2011-03-21 13:47 1268Android:只读EditText内容可滚动(禁止输入法)的 ... -
android 对话提示框大全
2011-03-21 12:34 3214Android 对话框(Dialog)大全 建立你自己的对话框 ... -
Android消息提示框和对话框
2011-03-21 12:29 1368在某些情况下需要向用户弹出提示消息,如显示错误信息,收到短消息 ... -
android tab 用法
2011-03-11 15:10 1776TabHost广泛运用于android程序中,在程序中运用Ta ...
相关推荐
本项目“基于Android的个人日记本程序”是一个典型的应用实例,它利用SQLite数据库实现了日记的存储、查询、编辑和删除功能,展现了Android应用程序与数据库结合的强大能力。以下将对该项目的关键技术点进行详细阐述...
以下是对这个“Android开发-日记本实例”的详细解析: 1. **基础UI组件**:在Android应用中,界面通常由各种UI组件构成,如TextView用于显示文本,EditText用于用户输入,Button用于触发操作,ListView或...
本实例“Android日记本”是针对初学者和有一定基础的开发者设计的,它基于Android 5.0(Lollipop)系统,能够正常运行,提供了一个完整的应用开发流程的示例。 首先,让我们深入了解一下Android应用程序的基本结构...
这个“Android本地数据库日记本”项目就是这样一个实例,它利用了SQLite数据库来存储用户的日记和笔记内容。下面我们将深入探讨相关的知识点。 首先,SQLite是一个轻量级的数据库系统,它是Android系统内置的,无需...
在Android编程中,SQLite是一个重要的组成部分,...总的来说,Android编程中的SQLite数据库是实现日记本应用的关键技术之一,通过学习和实践这些基本操作,开发者可以创建功能完备且用户友好的本地数据存储解决方案。
本项目"android-日记本"就是这样一个实例,它充分利用了SQLite数据库来实现日记的管理,包括添加、删除、修改和查询等功能,并将这些数据在ListView上进行展示,为用户提供直观的操作界面。 SQLite是Android系统...
在Android平台上开发一款个人日记本程序,SQLite数据库是不可或缺的核心技术。SQLite是一个轻量级的、嵌入式的关系型数据库,特别适合于移动设备,因为它不需要独立的服务进程,且占用资源少,操作简便。 首先,...
通过`SQLiteOpenHelper`,我们可以轻松地创建数据库和表,然后实现CRUD(创建、读取、更新、删除)操作。结合用户界面,我们可以创建功能丰富的应用程序,如“我的便签”,满足用户在本地保存和管理信息的需求。在...
【Android 日记本实现:时间轴与SQLite简单操作】 在Android开发中,构建一个日记本应用需要涉及到用户界面设计、数据存储以及时间轴展示等多个方面。在这个项目中,开发者使用了自定义的界面布局,实现了基本的...
本资源"Android日记系统源码(数据库的基本操作).zip"提供了一个实际的示例,展示了如何在Android应用中实现一个简单的日记系统,并涉及到数据库的基础操作。通过这个项目,我们可以深入理解Android中的SQLite...
总结,这个“Android的一个简单的日记工程(SQLite)”实例为我们提供了学习如何在Android应用中集成SQLite数据库、创建表、执行CRUD操作以及构建用户界面的实践经验。通过参考这个实例,开发者可以更好地理解和运用...
《Android Studio入门实战:打造个人日记本应用》 在Android开发领域,Android Studio作为官方推荐的集成开发环境(IDE),已经成为了开发者们的首选工具。本项目"JoneCool-Android-MyDiary-master"就是一个使用...
这款"android 日记本"源代码正是这样一个实例,它包含了基本的功能和简洁的实现,适合作为Android编程的入门教程。 首先,我们来探讨Android应用的基本架构。一个典型的Android应用由多个组件构成,包括Activity、...
《Android日记系统源码...综上所述,这个Android日记系统的源码实例涵盖了SQLite数据库的基本操作,是学习和实践Android数据库编程的好材料。通过研究源码,开发者可以更深入地理解Android中如何有效地管理和操作数据。
实例056: 编写一个手机日记本程序 170 实例057: 使用ContentProvider开发一个 手机日记本 177 实例058: 使用文件保存数据 188 实例059: 将网上的图片保存到SD卡并在 手机中显示出来 190 实例060: 保存联系人...
本压缩包中的"Android 日记系统源码(数据库的基本操作).rar"提供了关于如何在Android应用中使用SQLite数据库进行基本操作的实例。SQLite是Android系统内置的关系型数据库,非常适合小型数据存储需求,如日记应用。...
【Android应用源码之日记本.zip】是一个包含Android应用程序源代码的压缩文件,重点在于学习和研究Android开发。这个源码实例很可能是一个简单的日记应用程序,它可以帮助开发者理解如何在Android平台上构建用户友好...
【Android日记本源码】是一个深入探讨Android应用开发的实例,尤其关注布局设计与数据存储这两方面的技术。在这个项目中,开发者将学习如何构建一个功能齐全的日记应用程序,包括创建用户友好的界面、记录和保存用户...
### Android开发实例大全知识点总结 #### 第一章 UI布局开发实例集锦 1. **线性布局LinearLayout**:用于按照水平或垂直方向线性排列...通过阅读和实践这些实例,开发者可以更好地掌握Android应用开发的技巧和方法。
总的来说,"个人日记本"项目是一个全面的Android SQLite实战案例,涵盖了数据库的基本操作,以及与UI的交互,是提升Android数据库开发技能的好练习。通过这个项目,开发者可以深入理解Android中的数据存储机制,并...