本文是自己学习所做笔记。欢迎转载。但请注明出处:http://blog.csdn.net/jesson20121020

通过之前的10节,已实现了记事本的大部分功能,有加入拍照。加入照片,加入录音,加入画图,加入手写,另外细心的能够发现。底部菜单另一个很多其它的选项。这个以后再实现,用于扩展记事本的功能。

这节就来为我们的记事本加入数据库支持,这样,就能够在加入记事后将其保存在数据库中,方便下次浏览。改动,删除等。

先看效果图:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamVzc29uMjAxMjEwMjA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamVzc29uMjAxMjEwMjA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

三张图片分别演示了保存记事,查看记事。删除记事。

对于数据库而言,无非就是涉及到数据库的创建,增删改查。

为了将数据库的操作封装起来,单独写了一个类,例如以下:

数据库操作

DatabaseOperation.java

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Toast; public class DatabaseOperation {
private SQLiteDatabase db;
private Context context;
public DatabaseOperation(Context context,SQLiteDatabase db) {
this.db = db;
this.context = context;
}
//数据库的打开或创建
public void create_db(){
//创建或打开数据库
db = SQLiteDatabase.openOrCreateDatabase(context.getFilesDir().toString()+"/mynotes.db3", null);
db.execSQL("DROP TABLE IF EXISTS studentScore"); if(db == null){
Toast.makeText(context,"数据库创建不成功",Toast.LENGTH_LONG).show();
}
//Toast.makeText(context,"数据库创建成功",Toast.LENGTH_LONG).show(); //创建表
db.execSQL("create table if not exists notes(_id integer primary key autoincrement," +
"title text," +
"context text," +
"time varchar(20))"); }
public void insert_db(String title,String text,String time){ if(text.isEmpty()){
Toast.makeText(context, "各字段不能为空", Toast.LENGTH_LONG).show();
}
else{
db.execSQL("insert into notes(title,context,time) values('"+ title+"','"+ text+ "','"+time+"');");
//Toast.makeText(context, "插入成功", Toast.LENGTH_LONG).show();
} }
public void update_db(String title,String text,String time,int item_ID){
if( text.isEmpty()){
Toast.makeText(context, "各字段不能为空", Toast.LENGTH_LONG).show();
}
else{
//String sql = "update main set class1='" + class1 + "',class2='" + class2 + "',class3='" + class4 + "',class4='" + class4 + "'where days='" + days + "';";
db.execSQL("update notes set context='"+text+ "',title='"+title+"',time='"+time+"'where _id='" + item_ID+"'");
//Toast.makeText(context, "改动成功", Toast.LENGTH_LONG).show();
}
} public Cursor query_db(){
Cursor cursor = db.rawQuery("select * from notes",null);
return cursor;
}
public Cursor query_db(int item_ID){
Cursor cursor = db.rawQuery("select * from notes where _id='"+item_ID+"';",null);
return cursor; }
public void delete_db(int item_ID){
db.execSQL("delete from notes where _id='" + item_ID+"'");
//Toast.makeText(context, "删除成功", Toast.LENGTH_LONG).show();
}
//关闭数据库
public void close_db(){
db.close();
}
}

有了这些数据库的相关操作,以下就開始实现保存记事,改动记事,删除记事。查询记事的功能。

保存记事

当编辑好一个记事时。这时点击顶部的保存button,就将所写的记事插入到数据库中,当然了,假设记事里面有图片,录音等,并没有图片,录音本身存储到数据库,而是将其所在路径存储在数据库中,等到再次查看时。再从数据库中读取,并依据所保存的路径取出源文件。

保存记事的思想就是取出EditText中的内容,并从中截取前一部分作为该记事的标题,以及同一时候也保存了加入记事的时间。

主要代码为:

        //取得EditText中的内容
String context = et_Notes.getText().toString();
if(context.isEmpty()){
Toast.makeText(AddActivity.this, "记事为空!", Toast.LENGTH_LONG).show();
}
else{
//取得当前时间
SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm");
Date curDate = new Date(System.currentTimeMillis());//获取当前时间
String time = formatter.format(curDate);
//截取EditText中的前一部分作为标题,用于显示在主页列表中
String title = getTitle(context);
//打开数据库
dop.create_db();
//推断是更新还是新增记事
if(editModel.equals("newAdd")){
//将记事插入到数据库中
dop.insert_db(title,context,time);
}
//假设是编辑则更新记事就可以
else if(editModel.equals("update")){
dop.update_db(title,context,time,item_Id);
}
dop.close_db();
//结束当前activity
AddActivity.this.finish();
}

当中, getTitle()函数就是为了截取记事正文的前15字作为该记事的标题;editModel表示当前是新增记事还是改动记事。getTitle()例如以下:

       //截取EditText中的前一部分作为标题。用于显示在主页列表中
private String getTitle(String context){
    //定义正則表達式,用于匹配路径
Pattern p=Pattern.compile("/([^\\.]*)\\.\\w{3}");
Matcher m=p.matcher(context);
StringBuffer strBuff = new StringBuffer();
String title = "";
int startIndex = 0;
while(m.find()){
//取出路径前的文字
if(m.start() > 0){
strBuff.append(context.substring(startIndex, m.start()));
}
//取出路径
String path = m.group().toString();
//取出路径的后缀
String type = path.substring(path.length() - 3, path.length());
//推断附件的类型
if(type.equals("amr")){
strBuff.append("[录音]");
}
else{
strBuff.append("[图片]");
}
startIndex = m.end();
//仅仅取出前15个字作为标题
if(strBuff.length() > 15){
//统一将回车,等特殊字符换成空格
title = strBuff.toString().replaceAll("\r|\n|\t", " ");
return title;
}
}
strBuff.append(context.substring(startIndex, context.length()));
//统一将回车,等特殊字符换成空格
title = strBuff.toString().replaceAll("\r|\n|\t", " ");
return title;
}

这里主要是用到了正則表達式,用于匹配是普通文字还是图片录音等,假设是图片录音。则在标题中显然图片录音文字就可以,这里还用到了一个技巧,就是return 的上一句。目的就是为了将标题中的回车等特殊字符统一换成空格。

浏览(改动)记事

在保存了记事后,当然就要从数据库取出,并以原来的格式显示给用户。设想一下,在新增了记事后。返回主页或者又一次进入主页。就应该看到当前已保存的记事列表,所以在主页的Activity中应该放置一个列表(ListView)用于显示从数据库中取出的数据。

当点击列表的项目时,就应该打开查看该记事的具体内容了。

由于在保存记事时已经截取了一部分作为标题。所以在主页记事列表上仅仅显示标题,时间,而不显然具体内容。主要代码下:

private SQLiteDatabase db;
private DatabaseOperation dop;
private ListView lv_notes;
......
//数据库操作
dop = new DatabaseOperation(this, db);
lv_notes = (ListView)findViewById(R.id.lv_notes);
//显示记事列表
showNotesList();
//为记事列表加入监听器
lv_notes.setOnItemClickListener(new ItemClickEvent());

当中,showNotesList()就是用来显然记事列表的,例如以下:

    //显示记事列表
private void showNotesList(){
//创建或打开数据库
dop.create_db();
Cursor cursor = dop.query_db();
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
R.layout.note_item,
cursor,
new String[]{"_id","title","time"}, new int[]{R.id.tv_note_id,R.id.tv_note_title,R.id.tv_note_time});
lv_notes.setAdapter(adapter);
dop.close_db(); }

上面仅仅实现了浏览记事列表的功能,那么点击列表项目。自然就是查看或改动记事的具体内容了。所以为列表加入单击事件,并在其监听器中实现从数据库读取对应的记事内容。并显示,例如以下:

    //记事列表单击监听器
class ItemClickEvent implements OnItemClickListener{ @Override
public void onItemClick(AdapterView<? > parent, View view, int position,
long id) {
tv_note_id = (TextView)view.findViewById(R.id.tv_note_id);
int item_id = Integer.parseInt(tv_note_id.getText().toString());
Intent intent = new Intent(MainActivity.this,AddActivity.class);
intent.putExtra("editModel", "update");
intent.putExtra("noteId", item_id);
startActivity(intent);
}
}

这样。当单击一个列表项时。就会新打开一个activity,用于显示记事的具体内容,这里依旧用的是新增记事Activity,这样做的优点就是在查看记事的同一时候,也能够改动。这也是大多数记事软件所採用的方法,并且,也能过intent将一些信息传递给AddActivity,当中editModel是编辑模式。由于这里是查看或者改动,所以当再次点击保存时。就更新原有的记事就可以,并非又新添加一条记事;noteId是为了让AddActivity知道该读取数据库的中那一条数据。对应的。要在AddActivity里加入代码取出数据并显示,主要代码例如以下:

        //载入数据
private void loadData(){ //假设是新增记事模式。则将editText清空
if(editModel.equals("newAdd")){
et_Notes.setText("");
}
//假设编辑的是已存在的记事,则将数据库的保存的数据取出。并显示在EditText中
else if(editModel.equals("update")){
tv_title.setText("编辑记事"); dop.create_db();
Cursor cursor = dop.query_db(item_Id);
cursor.moveToFirst();
//取出数据库中对应的字段内容
String context = cursor.getString(cursor.getColumnIndex("context")); //定义正則表達式。用于匹配路径
Pattern p=Pattern.compile("/([^\\.]*)\\.\\w{3}");
Matcher m=p.matcher(context);
int startIndex = 0;
while(m.find()){
//取出路径前的文字
if(m.start() > 0){
et_Notes.append(context.substring(startIndex, m.start()));
} SpannableString ss = new SpannableString(m.group().toString()); //取出路径
String path = m.group().toString();
//取出路径的后缀
String type = path.substring(path.length() - 3, path.length());
Bitmap bm = null;
Bitmap rbm = null;
//推断附件的类型,假设是录音文件,则从资源文件里载入图片
if(type.equals("amr")){
bm = BitmapFactory.decodeResource(getResources(), R.drawable.record_icon);
//缩放图片
rbm = resize(bm,200); }
else{
//取出图片
bm = BitmapFactory.decodeFile(m.group());
//缩放图片
rbm = resize(bm,480);
} //为图片加入边框效果
rbm = getBitmapHuaSeBianKuang(rbm);
System.out.println(rbm.getWidth()+"-------"+rbm.getHeight());
ImageSpan span = new ImageSpan(this, rbm);
ss.setSpan(span,0, m.end() - m.start(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
et_Notes.append(ss);
startIndex = m.end();
}
//将最后一个图片之后的文字加入在TextView中
et_Notes.append(context.substring(startIndex,context.length()));
dop.close_db();
}
}

这里相同是用到了正則表達式。由于要识别路径。通过这种方法,在每次打开AddActivity时调用该方法,即能适用于新增记事,也能够用于改动记事。

删除记事

删除记事的实现还是在主页Activity中实现。当长按列表项目时。弹出操作选择,共同拥有两个。一个是编辑。一个是删除。这里的编辑是和单击列表项的查看记事的功能一样。主要是删除,当选中了删除时,就将对应的记事条目从数据库中删除,并刷新列表。主要代码例如以下:

......

//为记事列表加入长按事件
lv_notes.setOnItemLongClickListener(new ItemLongClickEvent());
...... //记事列表长按监听器
class ItemLongClickEvent implements OnItemLongClickListener{ @Override
public boolean onItemLongClick(AdapterView<? > parent, View view,
int position, long id) {
tv_note_id = (TextView)view.findViewById(R.id.tv_note_id);
int item_id = Integer.parseInt(tv_note_id.getText().toString());
simpleList(item_id);
return true;
} }
//简单列表对话框,用于选择操作
public void simpleList(final int item_id){
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this,R.style.custom_dialog);
alertDialogBuilder.setTitle("选择操作");
alertDialogBuilder.setIcon(R.drawable.ic_launcher);
alertDialogBuilder.setItems(R.array.itemOperation, new android.content.DialogInterface.OnClickListener() { @Override
public void onClick(DialogInterface dialog, int which) { switch(which){
//编辑
case 0 :
Intent intent = new Intent(MainActivity.this,AddActivity.class);
intent.putExtra("editModel", "update");
intent.putExtra("noteId", item_id);
startActivity(intent);
break;
//删除
case 1 :
dop.create_db();
dop.delete_db(item_id);
dop.close_db();
//刷新列表显示
lv_notes.invalidate();
showNotesList();
break;
}
}
});
alertDialogBuilder.create();
alertDialogBuilder.show();
}

以上。就实现了记事的保存,改动,删除的功能,到此。记事本的功能已基本完毕,剩下的就是兴许的完好与优化。以及新增功能了。

android项目 之 记事本(11) ----- 加入数据库的更多相关文章

  1. Android菜鸟成长记11 -- sqlite数据库的设计和升降级

    Google为Andriod的较大的数据处理提供了SQLite,他在数据存储.管理.维护等各方面都相当出色,功能也非常的强大.SQLite具备下列特点: 1.轻量级 使用 SQLite 只需要带一个动 ...

  2. android项目 之 记事本(12) ----- 图片的等比例缩放及给图片加入边框

    本文是自己学习所做笔记.欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020 在Android的UI开发中常常会遇到图片的缩放,就比方记事本,如今的图片都比較 ...

  3. android项目 之 记事本(6)----- 加入手写

    想必大家都用过QQ的白板功能,里面主要有两项,一个是涂鸦功能,事实上类似于上节的画板功能,而还有一个就是手写,那记事本怎么能没有这个功能呢,今天就来为我们的记事本加入手写功能. 先上图,看看效果: 看 ...

  4. android项目 之 记事本(13) ----- 查看图片及播放录音

    本文是自己学习所做笔记,欢迎转载.但请注明出处:http://blog.csdn.net/jesson20121020 今天就来实现下查看图片及录音的功能,在编辑或者浏览记事时,点击图片.打开一个自己 ...

  5. XamarinSQLite教程在Xamarin.Android项目中提取数据库文件

    XamarinSQLite教程在Xamarin.Android项目中提取数据库文件 由于不能直接打开该文件,开发者需要先将数据库文件从Android系统中提取出来.操作步骤如下. (5)选择MyDoc ...

  6. XamarinSQLite教程在Xamarin.Android项目中定位数据库文件

    XamarinSQLite教程在Xamarin.Android项目中定位数据库文件 实际开发中,经常需要验证数据库操作的正确性.这个时候,需要打开数据库文件,进行确认.下面是如何找到MyDocumen ...

  7. XamarinSQLite教程在Xamarin.Android项目中使用数据库

    XamarinSQLite教程在Xamarin.Android项目中使用数据库 在Xamarin.Android项目中使用预设数据库的具体操作步骤如下: (1)创建一个Xamarin.Android项 ...

  8. Android项目通过Android Debug Database实时查看本地Sqlite数据库内容

    前几天写Android项目时,想和Sqlyog那样图形化查看数据库中的文件,由于Android自带小型的Sqlite轻量级数据库,在查找方法时发现了一个特别简单适用的方法,纪录一下. 在android ...

  9. 让android项目支持boost 支持c++11

    在Application.mk 里增加-D__GLIBC__  让项目支持boost 增加 -std=c++11 让项目支持c++11 (3.x的cocos本身已经支持了的) 看起来这样: APP_S ...

随机推荐

  1. android 横竖屏切换不重走生命周期

    android在系统配置发生改变时,Activity会被重新创建,但是某些情况下我们希望系统配置改变时不会重新创建Activity,这个时候我们可以给Activity指定相对应的configChang ...

  2. Python模糊查询本地文件夹去除文件后缀(7行代码)

    Python模糊查询本地文件夹去除文件后缀 import os,re def fuzzy_search(path): word= input('请输入要查询的内容:') for filename in ...

  3. 如何兼容所有Android版本选择照片或拍照然后裁剪图片--基于FileProvider和动态权限的实现

    我们知道, Android操作系统一直在进化. 虽然说系统是越来越安全, 可靠, 但是对于开发者而言, 开发难度是越来越大的, 需要注意的兼容性问题, 也越来越多. 就比如在Android平台上拍照或 ...

  4. 基于python3.x,使用Tornado中的torndb模块操作数据库

    目前Tornado中的torndb模块是不支持python3.x,所以需要修改部分torndb源码即可正常使用 1.开发环境介绍 操作系统:win8(64位),python版本:python3.6(3 ...

  5. VMware系统克隆

    第1章 搭建VMware实战环境 1.1 vmware主机配置-网络配置 1.1.1 虚拟主机添加网卡信息(5) a.右键虚拟主机→设置→添加虚拟网卡硬件设备 b.设置网络适配器类型→完成添加 1.1 ...

  6. 【OpenCV】通过ROI区域以及掩码实现图像叠加

    在图像处理领域,我们常常需要设置感兴趣区域(ROI,region of interest),来专注或者简化我们的工作过程 .也就是从图像中选择的一个图像区域,这个区域是我们图像分析所关注的重点.我们圈 ...

  7. java非阻塞IO(NIO)流程

    单线程 多线程(Netty/Mina)

  8. 基于HTML5的WebGL经典3D虚拟机房漫游动画

    第一人称在 3D 中的用法要参考第一人称在射击游戏中的使用,第一人称射击游戏(FPS)是以第一人称视角为中心围绕枪和其他武器为基础的视频游戏类型 ; 也就是说,玩家通过主角的眼睛来体验动作.自从流派开 ...

  9. VIM于换行EOL的思考

    \n LF 0A 将当前光标切换到下一行(不一定行首)\r CR OD 将当前光标置于行首 在windows与unix系统中,unix将\n代表换行并置于行首,而windows保持原意.即unix:\ ...

  10. [转]Oracle 重建索引的必要性

    http://blog.csdn.net/leshami/article/details/23763963 索引重建是一个争论不休被不断热烈讨论的议题.当然Oracle官方也有自己的观点,我们很多DB ...