略。
先保留自动生成的布局文件activity_edit.xml文件。
NoteInfo需要实现Serializable接口,因为会使用Intent、Bundle来传输此类的实例。内容如下:
package com.zys.mynotebook; import java.io.Serializable; public class NoteInfo implements Serializable { private String id; private String title; private String content; private String date; //getter and setter }NoteDataBaseHelper类继承SQLiteOpenHelper(抽象)类,用来管理数据库的创建和版本的管理。内容如下:
package com.zys.mynotebook; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class NoteDataBaseHelper extends SQLiteOpenHelper { public NoteDataBaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } //表创建接口 有多张表时 方便统一调用 public static interface TableCreateInterface { //创建表 public void onCreate( SQLiteDatabase db ); //更新表 public void onUpgrade( SQLiteDatabase db, int oldVersion, int newVersion ); } @Override public void onCreate(SQLiteDatabase db) { //具体表的创建 Note.getInstance().onCreate(db); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //具体表的更新 Note.getInstance().onUpgrade(db,oldVersion,newVersion); } }Note类实现了前面NoteDataBaseHelper中的TableCreateInterface接口。内容如下:
package com.zys.mynotebook; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import java.util.HashMap; public class Note implements NoteDataBaseHelper.TableCreateInterface { // 定义表名 public static String tableName = "Note"; // 定义各字段名 public static String _id = "_id"; // _id是SQLite中自动生成的主键,用语标识唯一的记录,为了方便使用,此处定义对应字段名 public static String title = "title"; // 标题 public static String content = "content"; // 内容 public static String time = "date"; // 时间 //私有化构造方法 private Note(){} //初始化实例 private static Note note = new Note(); //只提供一个实例 public static Note getInstance(){ return note; } //实现表的创建 @Override public void onCreate(SQLiteDatabase db) { String sql = "CREATE TABLE " + Note.tableName + " ( " + "_id integer primary key autoincrement, " + Note.title + " TEXT, " + Note.content + " TEXT, " + Note.time + " TEXT " + ");"; db.execSQL( sql ); } //实现表的更新 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if ( oldVersion < newVersion ) { String sql = "DROP TABLE IF EXISTS " + Note.tableName; db.execSQL( sql ); this.onCreate( db ); } } // 插入 public static void insertNote( NoteDataBaseHelper dbHelper, ContentValues userValues ) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.insert( Note.tableName, null, userValues ); db.close(); } // 删除一条笔记 public static void deleteNote( NoteDataBaseHelper dbHelper, int _id ) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.delete( Note.tableName, Note._id + "=?",new String[] { _id + "" } ); db.close(); } // 删除所有笔记 public static void deleteAllNote( NoteDataBaseHelper dbHelper ) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.delete( Note.tableName, null, null ); db.close(); } // 修改 public static void updateNote( NoteDataBaseHelper dbHelper, int _id, ContentValues infoValues ) { SQLiteDatabase db = dbHelper.getWritableDatabase(); db.update(Note.tableName, infoValues, Note._id + " =? ", new String[]{ _id + "" }); db.close(); } // 以HashMap<String, Object>键值对的形式获取一条信息 public static HashMap<String, Object> getNote(NoteDataBaseHelper dbHelper, int _id ){ SQLiteDatabase db = dbHelper.getReadableDatabase(); HashMap<String, Object> NoteMap = new HashMap<String, Object>(); // 此处要求查询Note._id为传入参数_id的对应记录,使游标指向此记录 Cursor cursor = db.query( Note.tableName, null, Note._id + " =? ", new String[]{ _id + "" }, null, null, null); cursor.moveToFirst(); NoteMap.put(Note.title, cursor.getLong(cursor.getColumnIndex(Note.title))); NoteMap.put(Note.content, cursor.getString(cursor.getColumnIndex(Note.content))); NoteMap.put(Note.time, cursor.getString(cursor.getColumnIndex(Note.time))); return NoteMap; } // 获得查询指向Note表的游标 public static Cursor getAllNotes(NoteDataBaseHelper dbHelper) { SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = db.query(Note.tableName, null, null, null, null, null, null); cursor.moveToFirst(); return cursor; } }为主界面的ListView创建一个适配器类,实现自定义视图。内容如下:
package com.zys.mynotebook; import android.content.Context; import android.graphics.BitmapFactory; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.List; //item中所有的控件 class ViewHolder{ public ImageView itemIcon; public TextView itemNoteTitle; public TextView itemNoteDate; View itemView; public ViewHolder(View itemView) { if (itemView == null){ throw new IllegalArgumentException("item View can not be null!"); } this.itemView = itemView; itemIcon = itemView.findViewById(R.id.rand_icon); itemNoteTitle = itemView.findViewById(R.id.item_note_title); itemNoteDate = itemView.findViewById(R.id.item_note_date); } } public class ListAdapter extends BaseAdapter { private List<NoteInfo> noteList; private LayoutInflater layoutInflater; private Context context; private ViewHolder holder = null; public ListAdapter(Context context,List<NoteInfo> noteList) { this.noteList = noteList; this.context = context; layoutInflater = LayoutInflater.from(context); } @Override public int getCount() { return noteList.size(); } @Override public Object getItem(int position) { return noteList.get(position).getTitle(); } @Override public long getItemId(int position) { return Long.parseLong(noteList.get(position).getId()); } public void remove(int index){ noteList.remove(index); } public void refreshDataSet(){ notifyDataSetChanged(); } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null){ convertView = layoutInflater.inflate(R.layout.item_layout,null); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } //如果每个item的图片一样的话可以直接在布局文件中固定设置 holder.itemIcon.setImageBitmap(BitmapFactory.decodeResource( context.getResources(),R.drawable.note)); holder.itemNoteTitle.setText(noteList.get(position).getTitle()); holder.itemNoteDate.setText(noteList.get(position).getDate()); return convertView; } }在MainActivity的onCreate方法中实现初始化视图、设置监听器、为ListView设置适配器、创建数据库等操作。内容如下:
package com.zys.mynotebook; import android.app.AlertDialog; import android.content.ContentValues; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; import java.io.Serializable; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class MainActivity extends AppCompatActivity { private ListView noteListView; private Button addBtn; private List<NoteInfo> noteList = new ArrayList<>(); private ListAdapter mListAdapter; private static NoteDataBaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dbHelper = new NoteDataBaseHelper(this,"MyNote.db",null,1); //先测试添加一条数据 /*ContentValues values = new ContentValues(); values.put(Note.title,"测试笔记"); values.put(Note.content,"以下为测试内容!!!"); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); values.put(Note.time,sdf.format(date)); Note.insertNote(dbHelper,values);*/ initView(); setListener(); //跳转回主界面 刷新列表 Intent intent = getIntent(); if (intent != null){ getNoteList(); mListAdapter.refreshDataSet(); } } //初始化视图 private void initView(){ noteListView = findViewById(R.id.note_list); addBtn = findViewById(R.id.btn_add); //获取noteList getNoteList(); mListAdapter = new ListAdapter(MainActivity.this,noteList); noteListView.setAdapter(mListAdapter); } //设置监听器 private void setListener(){ addBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this,EditActivity.class); startActivity(intent); } }); noteListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { NoteInfo noteInfo = noteList.get(position); Intent intent = new Intent(); Bundle bundle = new Bundle(); bundle.putSerializable("noteInfo",(Serializable)noteInfo); intent.putExtras(bundle); intent.setClass(MainActivity.this, EditActivity.class); startActivity(intent); } }); noteListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) { final NoteInfo noteInfo = noteList.get(position); String title = "警告"; new AlertDialog.Builder(MainActivity.this) .setIcon(R.drawable.note) .setTitle(title) .setMessage("确定要删除吗?") .setPositiveButton(R.string.btn_confirm, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Note.deleteNote(dbHelper,Integer.parseInt(noteInfo.getId())); noteList.remove(position); mListAdapter.refreshDataSet(); Toast.makeText(MainActivity.this,"删除成功!",Toast.LENGTH_LONG).show(); } }) .setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }).create().show(); return true; } }); } //从数据库中读取所有笔记 封装成List<NoteInfo> private void getNoteList(){ noteList.clear(); Cursor allNotes = Note.getAllNotes(dbHelper); for (allNotes.moveToFirst(); !allNotes.isAfterLast(); allNotes.moveToNext()){ NoteInfo noteInfo = new NoteInfo(); noteInfo.setId(allNotes.getString(allNotes.getColumnIndex(Note._id))); noteInfo.setTitle(allNotes.getString(allNotes.getColumnIndex(Note.title))); noteInfo.setContent(allNotes.getString(allNotes.getColumnIndex(Note.content))); noteInfo.setDate(allNotes.getString(allNotes.getColumnIndex(Note.time))); noteList.add(noteInfo); } } //重写返回按钮处理事件 @Override public void onBackPressed() { String title = "提示"; new AlertDialog.Builder(MainActivity.this) .setIcon(R.drawable.note) .setTitle(title) .setMessage("确定要退出吗?") .setPositiveButton(R.string.btn_confirm, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { finish(); } }) .setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }).create().show(); } //给其他类提供dbHelper public static NoteDataBaseHelper getDbHelper() { return dbHelper; } }在浏览、更新界面中需要区分是处于插入(添加)状态还是更新状态。可以通过在onCreate方法中获取当前上下文中的Intent和Bundle对象,若Bundle为空,则说明处于插入(添加)状态,否则处于更新状态。内容如下:
package com.zys.mynotebook; import android.app.AlertDialog; import android.content.ContentValues; import android.content.DialogInterface; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import java.text.SimpleDateFormat; import java.util.Date; public class EditActivity extends AppCompatActivity { private Button btn_save; private Button btn_return; private TextView tv_now; private EditText et_title; private EditText et_content; //记录当前编辑的笔记对象(用于比对是否改变) private NoteInfo currentNote; //记录是否是插入状态 (因为也可能是更新(编辑)状态) private boolean insertFlag = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_edit); initView(); setListener(); Intent intent = getIntent(); Bundle bundle = intent.getExtras(); //主界面点击ListView中的一个Item跳转时 if(bundle != null){ currentNote = (NoteInfo) bundle.getSerializable("noteInfo"); et_title.setText(currentNote.getTitle()); et_content.setText(currentNote.getContent()); insertFlag = false; } } //初始化视图 private void initView(){ btn_save = findViewById(R.id.btn_save); btn_return = findViewById(R.id.btn_return); tv_now = findViewById(R.id.tv_now); et_content = findViewById(R.id.edit_content); et_title = findViewById(R.id.edit_title); Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); tv_now.setText(sdf.format(date)); } //设置监听器 private void setListener(){ btn_return.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onBackPressed(); } }); btn_save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if ( et_title.getText().toString().equals("") || et_content.getText().toString().equals("")){ Toast.makeText(EditActivity.this,R.string.save_fail,Toast.LENGTH_LONG).show(); }else { saveNote(); Intent intent = new Intent(EditActivity.this,MainActivity.class); startActivity(intent); } } }); } //保存笔记到数据库 判断是新建还是更新 private void saveNote(){ NoteDataBaseHelper dbHelper = MainActivity.getDbHelper(); ContentValues values = new ContentValues(); values.put(Note.title,et_title.getText().toString()); values.put(Note.content,et_content.getText().toString()); values.put(Note.time,tv_now.getText().toString()); if (insertFlag){ Note.insertNote(dbHelper,values); }else{ Note.updateNote(dbHelper,Integer.parseInt(currentNote.getId()),values); } } //重写手机上返回按键处理函数,如果更改了提示保存 否则直接返回主界面 @Override public void onBackPressed() { boolean display = false; if (insertFlag){ if( !et_title.getText().toString().equals("") && !et_content.getText().toString().equals("")){ display = true; } }else{ if( !et_title.getText().toString().equals(currentNote.getTitle()) || !et_content.getText().toString().equals(currentNote.getContent())){ display = true; } } if (display){ String title = "警告"; new AlertDialog.Builder(EditActivity.this) .setIcon(R.drawable.note) .setTitle(title) .setMessage("是否保存当前内容?") .setPositiveButton(R.string.btn_confirm, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { saveNote(); Toast.makeText(EditActivity.this,R.string.save_succ,Toast.LENGTH_LONG).show(); //更新当前Note对象的值 防止选择保存后按返回仍显示此警告对话框 currentNote.setTitle(et_title.getText().toString()); currentNote.setContent(et_content.getText().toString()); } }) .setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Intent intent = new Intent(EditActivity.this,MainActivity.class); startActivity(intent); } }).create().show(); }else{ Intent intent = new Intent(EditActivity.this,MainActivity.class); startActivity(intent); } } }运行程序后,可以在Android Studio中的Device File Explorer中的data->data->com.zys.mynotebook->databases目录下看到创建的数据库相关文件MyNote.db、MyNote.db-shm、MyNote.db-wal。
主界面(实现插入了测试数据) 点击列表项浏览 主界面点击添加按钮 输入内容,当标题或内容为空时,点击保存或返回(点击返回按钮、手机上的返回键)并选择保存时 补全内容,点击返回(点击返回按钮、手机上的返回键),提示保存 选择确定。也有Toast提示,没有成功截下…选择取消时会放弃保存并跳转到主界面 主界面长按列表项 选择删除,提示删除成功 我的其他文章:Android实战:利用service实现简单的音乐播放器我的更多文章尽在:我的个人博客
