写了一个AndroID记事本小程序,现在记录一下。
考虑到是记事本小程序,记录的内容只有文字,而且内容不会太长,所以选择使用sqlite数据库,数据存放在用户的手机上。
牵涉到数据库,那自然是一个实体。先设计实体数据表:DBHelper.java
package com.ikok.notepad.DBUtil; import androID.content.Context; import androID.database.sqlite.sqliteDatabase; import androID.database.sqlite.sqliteOpenHelper; /** * Created by Anonymous on 2016/3/24. */ public class DBHelper extends sqliteOpenHelper { /** * 创建笔记表 */ private static final String CREATE_NOTE = "create table Note(" + "ID integer primary key autoincrement," + "content text," + "time text)"; private Context mContext; public DBHelper(Context context,String name,sqliteDatabase.CursorFactory factory,int version) { super(context,name,factory,version); mContext = context; } @OverrIDe public voID onCreate(sqliteDatabase sqliteDatabase) { sqliteDatabase.execsql(CREATE_NOTE); // Toast.makeText(mContext,"Created",Toast.LENGTH_SHORT).show(); } @OverrIDe public voID onUpgrade(sqliteDatabase sqliteDatabase,int i,int i1) { } }
创建完数据表后,自然需要 *** 作数据库,CRUD数据,我把所有跟数据库有关的 *** 作封装在一起:NoteDB.java
package com.ikok.notepad.DBUtil; import androID.content.ContentValues; import androID.content.Context; import androID.database.Cursor; import androID.database.sqlite.sqliteDatabase; import com.ikok.notepad.Entity.Note; import java.util.ArrayList; import java.util.List; /** * Created by Anonymous on 2016/3/24. */ public class NoteDB { public static final String DB_name = "notepad"; public static final int VERSION = 1; private static NoteDB mNoteDB; private sqliteDatabase db; public NoteDB(Context context) { DBHelper dbHelper = new DBHelper(context,DB_name,null,VERSION); db = dbHelper.getWritableDatabase(); } /** * 获取 NoteDB 的实例 * @param context * @return */ public synchronized static NoteDB getInstance(Context context){ if (mNoteDB == null){ mNoteDB = new NoteDB(context); } return mNoteDB; } public voID saveNote(Note note){ if (note != null) { ContentValues values = new ContentValues(); values.put("content",note.getContent()); values.put("time",note.getTime()); db.insert("Note",values); } } public List<Note> loadNotes(){ List<Note> noteList = new ArrayList<Note>(); /** * 先按时间降序排列,再按ID降序排列 */ Cursor cursor = db.query("Note","time desc,ID desc"); if (cursor.movetoNext()){ do { Note note = new Note(); note.setID(cursor.getInt(cursor.getColumnIndex("ID"))); note.setContent(cursor.getString(cursor.getColumnIndex("content"))); note.setTime(cursor.getString(cursor.getColumnIndex("time"))); noteList.add(note); } while (cursor.movetoNext()); } return noteList; } public Note loadByID(int ID){ Note note = null; Cursor cursor = db.query("Note","ID = " + ID,null); if (cursor.movetoNext()){ note = new Note(); note.setContent(cursor.getString(cursor.getColumnIndex("content"))); note.setTime(cursor.getString(cursor.getColumnIndex("time"))); } return note; } public voID deleteByID(Integer ID){ db.delete("Note",null); } public voID deleteallNote(){ db.delete("Note",null); } public voID updateByID(String noteTime,String noteContent,int noteID){ ContentValues values = new ContentValues(); values.put("content",noteContent); values.put("time",noteTime); db.update("Note",values,"ID = " + noteID,null); } }
设计完数据库后,与数据库对应的需要一个实体类:Note.java
package com.ikok.notepad.Entity; import java.io.Serializable; /** * Created by Anonymous on 2016/3/24. */ public class Note implements Serializable { private int ID; private String content; private String time; public int getID() { return ID; } public voID setID(int ID) { this.ID = ID; } public String getContent() { return content; } public voID setContent(String content) { this.content = content; } public String getTime() { return time; } public voID setTime(String time) { this.time = time; } }
接下来进行App主页的设计:main_activity.xml
<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="@drawable/repeat_bg" androID:orIEntation="vertical"> <TextVIEw androID:ID="@+ID/app_Title" androID:layout_wIDth="match_parent" androID:layout_height="40dp" androID:textSize="16sp" androID:gravity="center" androID:text="@string/app_Title" androID:textcolor="#333" /> <ListVIEw androID:ID="@+ID/ListvIEw" androID:descendantFocusability="blocksDescendants" androID:layout_wIDth="match_parent" androID:layout_height="0dp" androID:layout_weight="1"> </ListVIEw> <relativeLayout androID:layout_wIDth="match_parent" androID:layout_height="40dp" > <Imagebutton androID:ID="@+ID/about_btn" androID:src="@drawable/about_me" androID:layout_alignParentleft="true" androID:paddingleft="20dp" androID:background="#00ffffff" androID:scaleType="center" androID:layout_margintop="4dp" androID:layout_wIDth="52dp" androID:layout_height="32dp" /> <TextVIEw androID:ID="@+ID/note_num" androID:layout_wIDth="wrap_content" androID:layout_height="30dp" androID:paddingtop="2dp" androID:textSize="18sp" androID:textcolor="#333" androID:layout_centerInParent="true" androID:text="@string/app_Title" /> <Imagebutton androID:ID="@+ID/write_btn" androID:src="@drawable/write_btn" androID:layout_alignParentRight="true" androID:paddingRight="20dp" androID:background="#00ffffff" androID:scaleType="center" androID:layout_margintop="4dp" androID:layout_wIDth="52dp" androID:layout_height="32dp" /> </relativeLayout> </linearLayout>
具体效果如下(图标懒得去改颜色了):
左边的是一个关于App的按钮,右边的新建记事本的按钮。
因为主页需要显示已经记录的内容,所以我选择用ListVIEw去显示。用到ListVIEw,则与之对应的是要一个数据源,一个适配器。所以我为每一条子项设计了一个样式,去让它左边显示创建或更新的时间,右边显示内容。如下:List_item.xml
<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:minHeight="50dp" androID:orIEntation="horizontal"> <TextVIEw androID:ID="@+ID/show_time" androID:layout_wIDth="wrap_content" androID:layout_height="match_parent" androID:gravity="center" androID:paddingleft="10dp" androID:textcolor="#333" androID:textSize="16sp" /> <TextVIEw androID:ID="@+ID/show_content" androID:layout_wIDth="0dp" androID:layout_weight="1" androID:layout_height="match_parent" androID:textSize="16sp" androID:paddingleft="20dp" androID:textcolor="#333" androID:paddingtop="14dp" androID:singleline="true" /> </linearLayout>
创建好了ListVIEw,接下来为它准备适配器:MyAdapter.java
package com.ikok.notepad.Util; import androID.content.Context; import androID.vIEw.LayoutInflater; import androID.vIEw.VIEw; import androID.vIEw.VIEwGroup; import androID.Widget.BaseAdapter; import androID.Widget.ListVIEw; import androID.Widget.TextVIEw; import com.ikok.notepad.Entity.Note; import com.ikok.notepad.R; import java.util.List; /** * Created by Anonymous on 2016/3/24. */ public class MyAdapter extends BaseAdapter { private List<Note> noteList; private LayoutInflater mInflater; private Context mContext; private int index; public MyAdapter(Context context,List<Note> noteList,ListVIEw ListVIEw) { this.mInflater = LayoutInflater.from(context); this.noteList = noteList; this.mContext = context; } @OverrIDe public int getCount() { return noteList.size(); } @OverrIDe public Object getItem(int i) { return noteList.get(i); } @OverrIDe public long getItemID(int i) { return i; } @OverrIDe public VIEw getVIEw(int i,VIEw convertVIEw,VIEwGroup vIEwGroup) { VIEwHolder vIEwHolder = null; if (convertVIEw == null){ vIEwHolder = new VIEwHolder(); convertVIEw = mInflater.inflate(R.layout.List_item,null); vIEwHolder.mTime = (TextVIEw) convertVIEw.findVIEwByID(R.ID.show_time); vIEwHolder.mContent = (TextVIEw) convertVIEw.findVIEwByID(R.ID.show_content); convertVIEw.setTag(vIEwHolder); } else { vIEwHolder = (VIEwHolder) convertVIEw.getTag(); } vIEwHolder.mTime.setText(noteList.get(i).getTime()); vIEwHolder.mContent.setText(noteList.get(i).getContent()); index = i; // convertVIEw.setonClickListener(new VIEw.OnClickListener() { // @OverrIDe // public voID onClick(VIEw vIEw) { // Intent intent = new Intent(mContext,UpdateOrReadActivity.class); //// Bundle bundle = new Bundle(); //// bundle.putSerializable("note_item",noteList.get(index)); //// intent.putExtras(bundle); // intent.putExtra("note_ID",noteList.get(index).getID()); // Log.d("Anonymous","备忘录ID:"+noteList.get(index).getID()); // mContext.startActivity(intent); // Log.d("Anonymous","执行了适配器里的点击事件"); // } // }); return convertVIEw; } class VIEwHolder{ public TextVIEw mTime; public TextVIEw mContent; } }
这里采用了使用VIEwHolder,来使ListVIEw滚动的时候不必每次重新创建对象,提升性能。
创建好了ListVIEw,准备好了适配器,接下来要为ListVIEw准备数据源,而这数据源是要从数据库读出来的。但是数据库 *** 作和网络访问等都是属于耗时 *** 作,如果用主UI线程去执行响应 *** 作的话,很可能会出现ANR现象,所以这里我用AsyncTask去执行数据库 *** 作。主Activity代码如下:MainActivity.java
package com.ikok.notepad.Activity; import androID.app.Activity; import androID.content.DialogInterface; import androID.content.Intent; import androID.os.AsyncTask; import androID.os.Bundle; import androID.support.v7.app.AlertDialog; import androID.vIEw.VIEw; import androID.vIEw.Window; import androID.Widget.AdapterVIEw; import androID.Widget.Imagebutton; import androID.Widget.ListVIEw; import androID.Widget.TextVIEw; import com.ikok.notepad.DBUtil.NoteDB; import com.ikok.notepad.Entity.Note; import com.ikok.notepad.R; import com.ikok.notepad.Util.DeleteAsyncTask; import com.ikok.notepad.Util.MyAdapter; import java.util.ArrayList; import java.util.List; /** * Created by Anonymous on 2016/3/24. */ public class MainActivity extends Activity { /** * 布局控件 */ private TextVIEw mTitle; private TextVIEw mNoteNum; private Imagebutton mWrite; private ListVIEw mNoteListVIEw; private Imagebutton mAbout; /** * 数据库实例,数据源 */ private List<Note> mNoteList = new ArrayList<Note>() ; private NoteDB mNoteDB; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestwindowFeature(Window.FEATURE_NO_Title); setContentVIEw(R.layout.main_activity); initVIEw(); new NewAsyncTask().execute(); initEvent(); } private voID initEvent() { /** * 新写一条备忘录 */ mWrite.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw vIEw) { Intent intent = new Intent(MainActivity.this,AddNoteActivity.class); startActivity(intent); } }); /** * 修改或查看一条已有的备忘录 */ mNoteListVIEw.setonItemClickListener(new AdapterVIEw.OnItemClickListener() { @OverrIDe public voID onItemClick(AdapterVIEw<?> adapterVIEw,VIEw vIEw,long l) { Note note = (Note) adapterVIEw.getItemAtposition(i); // Log.d("Anonymous","点击ListVIEw获取的note ID: " + note.getID()); Intent intent = new Intent(MainActivity.this,UpdateOrReadActivity.class); intent.putExtra("note_ID",note.getID()); startActivity(intent); } }); /** * ListvIEw长按删除 */ mNoteListVIEw.setonItemLongClickListener(new AdapterVIEw.OnItemLongClickListener() { @OverrIDe public boolean onItemLongClick(AdapterVIEw<?> parent,int position,long ID) { final Note note = (Note) parent.getItemAtposition(position); // Log.d("Anonymous","长按ListVIEw获取的note ID: " + note.getID()); /** * 长按提示是否删除 */ new AlertDialog.Builder(MainActivity.this) .setTitle("提示") .setMessage("真的要删除这条记录吗?") .setPositivebutton("确定",new DialogInterface.OnClickListener() { @OverrIDe public voID onClick(DialogInterface dialog,int which) { new DeleteAsyncTask(mNoteDB).execute(note.getID()); new NewAsyncTask().execute(); } }) .setNegativebutton("取消",null) .show(); return true; } }); /** * 关于自己 */ mAbout.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw v) { Intent intent = new Intent(MainActivity.this,AboutActivity.class); startActivity(intent); } }); } public voID initVIEw() { /** * 布局控件初始化 */ mTitle = (TextVIEw) findVIEwByID(R.ID.app_Title); // 画TextVIEw文字下的下划线 // mTitle.getPaint().setFlags(Paint.UNDERliNE_TEXT_FLAG); mNoteNum = (TextVIEw) findVIEwByID(R.ID.note_num); mWrite = (Imagebutton) findVIEwByID(R.ID.write_btn); mNoteListVIEw = (ListVIEw) findVIEwByID(R.ID.ListvIEw); mAbout = (Imagebutton) findVIEwByID(R.ID.about_btn); /** * 获取数据库实例 */ mNoteDB = NoteDB.getInstance(this); } /** * 异步加载备忘录 */ class NewAsyncTask extends AsyncTask<VoID,VoID,List<Note>>{ @OverrIDe protected List<Note> doInBackground(VoID... voIDs) { mNoteList = mNoteDB.loadNotes(); return mNoteList; } @OverrIDe protected voID onPostExecute(List<Note> notes) { super.onPostExecute(notes); /** * 设置适配器,绑定适配器 */ MyAdapter myAdapter = new MyAdapter(MainActivity.this,notes,mNoteListVIEw); mNoteListVIEw.setAdapter(myAdapter); /** * 更新备忘录记录数 */ int temp = mNoteList.size(); mNoteNum.setText("共 " + temp + " 条备忘录"); } } /** * 当活动恢复时,刷新ListvIEw和备忘录记录数 */ @OverrIDe protected voID onResume() { super.onResume(); new NewAsyncTask().execute(); } }
在上面的代码中,我新建了一个 NewAsyncTask 类去继承 AsyncTask,去执行从数据库读取数据的 *** 作,在onPostExecute()方法中,去更新UI,比如显示ListVIEw中的数据,一下页面底部中间有几条数据等。还有我考虑了新建记事本的话,是另外一个Activity。当从另外的Activity返回到主Activity时,主页面应该再刷新一次,刷新数据和显示,所以我在onResume()方法中调用了 NewAsyncTask().execute() 方法,当活动恢复时刷新显示。
接下来是新建记事本的Activity,布局如下:write_note.xml
<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:ID="@+ID/screen_vIEw" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="@drawable/repeat_bg" androID:orIEntation="vertical"> <relativeLayout androID:layout_wIDth="match_parent" androID:layout_height="40dp"> <Imagebutton androID:ID="@+ID/back_btn" androID:src="@drawable/back_btn" androID:layout_alignParentleft="true" androID:paddingleft="5dp" androID:background="#00ffffff" androID:scaleType="center" androID:layout_margintop="6dp" androID:layout_wIDth="52dp" androID:layout_height="32dp" /> <TextVIEw androID:ID="@+ID/complete_btn" androID:layout_alignParentRight="true" androID:paddingtop="10dp" androID:paddingRight="10dp" androID:textSize="18sp" androID:textcolor="#ec6d51" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:text="@string/complete"/> </relativeLayout> <EditText androID:ID="@+ID/note_content" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:paddingleft="10dp" androID:paddingRight="10dp" androID:textcolor="#333" androID:textCursorDrawable="@null" androID:background="@null"/> </linearLayout>
具体效果如下:
新建记事本的Activity如下:AddNoteActivity.java
package com.ikok.notepad.Activity; import androID.app.Activity; import androID.content.DialogInterface; import androID.os.AsyncTask; import androID.os.Bundle; import androID.support.v7.app.AlertDialog; import androID.vIEw.VIEw; import androID.vIEw.Window; import androID.Widget.EditText; import androID.Widget.Imagebutton; import androID.Widget.TextVIEw; import androID.Widget.Toast; import com.ikok.notepad.DBUtil.NoteDB; import com.ikok.notepad.Entity.Note; import com.ikok.notepad.R; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by Anonymous on 2016/3/24. */ public class AddNoteActivity extends Activity { /** * 布局控件 */ private TextVIEw mComplete; private Imagebutton mBackBtn; private EditText mContent; /** * 备忘录数据 */ private String noteTime; private String noteContent; /** * 数据库 */ private NoteDB mNoteDB; private Note note; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestwindowFeature(Window.FEATURE_NO_Title); setContentVIEw(R.layout.write_note); initVIEw(); initEvent(); } private voID initVIEw() { /** * 布局控件初始化 */ mComplete = (TextVIEw) findVIEwByID(R.ID.complete_btn); mBackBtn = (Imagebutton) findVIEwByID(R.ID.back_btn); mContent = (EditText) findVIEwByID(R.ID.note_content); /** * 获取数据库实例 */ mNoteDB = NoteDB.getInstance(this); } /** * 事件处理 */ private voID initEvent() { /** * 返回上一级菜单,如果有内容,提示是否保存 * 是、保存,销毁活动;否,直接销毁活动 */ mBackBtn.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw vIEw) { saveDataOrNot(); } }); /** * 完成按钮,保存备忘录到数据库 */ mComplete.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw vIEw) { if (!mContent.getText().toString().equals("")){ new AddAsyncTask().execute(); finish(); } else { finish(); } } }); } /** * 根据是否有内容,提示保存 */ private voID saveDataOrNot() { if (!mContent.getText().toString().trim().equals("")) { new AlertDialog.Builder(AddNoteActivity.this) .setTitle("提示") .setMessage("需要保存您编辑的内容吗?") .setPositivebutton("确定",new DialogInterface.OnClickListener() { @OverrIDe public voID onClick(DialogInterface dialog,int which) { new AddAsyncTask().execute(); finish(); } }) .setNegativebutton("取消",new DialogInterface.OnClickListener() { @OverrIDe public voID onClick(DialogInterface dialog,int which) { finish(); } }) .show(); } else { finish(); } } /** * 添加数据到数据库 */ class AddAsyncTask extends AsyncTask<VoID,VoID>{ @OverrIDe protected VoID doInBackground(VoID... voIDs) { mNoteDB.saveNote(note); return null; } @OverrIDe protected voID onPreExecute() { super.onPreExecute(); /** * 记录数据 */ SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm"); Date date = new Date(System.currentTimeMillis()); noteTime = sdf.format(date); noteContent = mContent.getText().toString(); note = new Note(); note.setTime(noteTime); note.setContent(noteContent); } @OverrIDe protected voID onPostExecute(VoID aVoID) { super.onPostExecute(aVoID); Toast.makeText(AddNoteActivity.this,"保存成功!",Toast.LENGTH_SHORT).show(); } } /** * 按返回键,有内容时,提示保存 */ @OverrIDe public voID onBackpressed() { saveDataOrNot(); } }
新建记事本,插入数据到数据库,如从数据库读取数据一样,都是耗时 *** 作,所以我还是用了AsyncTask,在 onPreExecute()方法中,先获取到系统当前时间,进行格式化,存储下来,把输入的文本存储下来,然后再 doInBackground()去保存数据。这里我考虑了,用户输入了内容,但是没有保存,在顶部的返回键或者系统的返回键的处理事件中都加了判断。如果文本为空,空格也算空,则不保存,直接退出当前Activity,如果有内容,则d出对话框提示用户是否保存,是则保存,否则不保存,退出当前活动。
接下来是查看或修改一条记事本了,布局我是直接复用新建记事本的布局。因为没有区别 - -
接下来是查看或修改一条记事本的Activity了,之前,我想的是点击一条记事本,则进入这条记事本,把这条记事本直接显示在页面上,用户直接在内容最后进行编辑。所以这里需要一个子项点击事件。我在MainActivity里已经写了,先获取当前点击的这一项的对象,这里我费了好多时间,我不知道点击这一项的时候,怎么把该项的对象读取出来。最后自己查看源码,查API,看到参数中AdapterVIEw是个泛型,我试着从它着手,把它强转成Note对象,然后试试获取ID,没想到就成了。 - -
所以,我获取了当前点击的item中的Note对象的ID,把它放在Intent中,带着这个参数去开启活动。
这里,查看或修改一条记事本的Activity正式开始了,如下:UpdateOrReadActivity.java
package com.ikok.notepad.Activity; import androID.app.Activity; import androID.content.DialogInterface; import androID.content.Intent; import androID.os.AsyncTask; import androID.os.Bundle; import androID.support.v7.app.AlertDialog; import androID.util.Log; import androID.vIEw.VIEw; import androID.vIEw.Window; import androID.Widget.EditText; import androID.Widget.Imagebutton; import androID.Widget.linearLayout; import androID.Widget.TextVIEw; import com.ikok.notepad.DBUtil.NoteDB; import com.ikok.notepad.Entity.Note; import com.ikok.notepad.R; import com.ikok.notepad.Util.DeleteAsyncTask; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by Anonymous on 2016/3/24. */ public class UpdateOrReadActivity extends Activity { /** * 布局控件 */ private TextVIEw mComplete; private Imagebutton mBackBtn; private EditText mContent; private linearLayout mScreen; /** * 备忘录数据 */ private int noteID; private String noteTime; private String noteContent; private String originData; /** * 数据库 */ private NoteDB mNoteDB; private static Note note; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestwindowFeature(Window.FEATURE_NO_Title); setContentVIEw(R.layout.write_note); /** * 获取传递过来的note对象 */ Intent intent = getIntent(); // 传递Note对象,必须要Note实体实现Serializable // note = (Note) intent.getSerializableExtra("note_item"); noteID = intent.getIntExtra("note_ID",0); Log.d("Anonymous","传递后的备忘录ID:" + noteID); initVIEw(); /** * 加载显示数据 */ new LoadAsyncTask().execute(); initEvent(); } private voID initVIEw() { /** * 布局控件初始化 */ mComplete = (TextVIEw) findVIEwByID(R.ID.complete_btn); mBackBtn = (Imagebutton) findVIEwByID(R.ID.back_btn); mContent = (EditText) findVIEwByID(R.ID.note_content); mScreen = (linearLayout) findVIEwByID(R.ID.screen_vIEw); /** * 获取数据库实例 */ mNoteDB = NoteDB.getInstance(this); } private voID initEvent() { /** * 返回上一级菜单,直接销毁当前活动 */ mBackBtn.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw vIEw) { updateDataOrNot(); } }); /** * 完成按钮,修改备忘录到数据库 */ mComplete.setonClickListener(new VIEw.OnClickListener() { @OverrIDe public voID onClick(VIEw vIEw) { if (mContent.getText().toString().trim().equals("")){ // Log.d("Anonymous","进入判断为空函数"); new DeleteAsyncTask(mNoteDB).execute(noteID); finish(); } else if (mContent.getText().toString().equals(originData)) { finish(); } else { // Log.d("Anonymous","进入判断不为空函数"); new UpdateAsyncTask().execute(); // Toast.makeText(UpdateOrReadActivity.this,"修改成功!",Toast.LENGTH_SHORT).show(); finish(); } } }); /** * 点击屏幕空白区域,EditText选中 */ } /** * 根据ID从数据库读数据的异步任务 */ class LoadAsyncTask extends AsyncTask<VoID,Note>{ @OverrIDe protected Note doInBackground(VoID... voIDs) { note = mNoteDB.loadByID(noteID); return note; } @OverrIDe protected voID onPostExecute(Note note) { super.onPostExecute(note); /** * 根据传递进来的Note显示备忘录内容,并把光标移动到最后 * 记录最初的文本内容 */ originData = note.getContent(); mContent.setText(note.getContent()); mContent.setSelection(mContent.getText().toString().length()); } } /** * 更新数据库的异步任务 */ class UpdateAsyncTask extends AsyncTask<VoID,VoID>{ @OverrIDe protected voID onPreExecute() { super.onPreExecute(); /** * 记录数据 */ SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm"); Date date = new Date(System.currentTimeMillis()); noteTime = sdf.format(date); noteContent = mContent.getText().toString(); note.setTime(noteTime); note.setContent(noteContent); } @OverrIDe protected VoID doInBackground(VoID... voIDs) { mNoteDB.updateByID(noteTime,noteContent,noteID); return null; } } /** * 根据是否有内容,提示保存 */ private voID updateDataOrNot() { if (!mContent.getText().toString().equals(originData)) { new AlertDialog.Builder(UpdateOrReadActivity.this) .setTitle("提示") .setMessage("需要保存您编辑的内容吗?") .setPositivebutton("确定",int which) { new UpdateAsyncTask().execute(); finish(); } }) .setNegativebutton("取消",int which) { finish(); } }) .show(); } else { finish(); } } /** * 返回键事件 * 根据内容是否有变化,提示是否保存 */ @OverrIDe public voID onBackpressed() { updateDataOrNot(); } }
*** 作数据库还是用了AsyncTask。这里,我考虑了,是否有改动,用一个变量,去存放原始的数据,在用户点击顶部返回或者系统返回键的时候去判断是否有改动,如果有,则提示用户是否需要保存更改。如果修改内容,没有字了,则自动删除该条记事本。因为删除记事本的 *** 作,在主页还需要用到,所以我把它提出来,单独作为一个类,不再是内部类了。如下:
package com.ikok.notepad.Util; import androID.os.AsyncTask; import com.ikok.notepad.DBUtil.NoteDB; /** * Created by Anonymous on 2016/3/25. */ public class DeleteAsyncTask extends AsyncTask<Integer,VoID> { private NoteDB noteDB; public DeleteAsyncTask(NoteDB noteDB) { this.noteDB = noteDB; } @OverrIDe protected VoID doInBackground(Integer... params) { noteDB.deleteByID(params[0]); return null; } }
接下来是CRUD的最后一项,删除数据了,在主页的时候,我设计的是单击进入该条记事本,去查看或修改这一条记事本,然后我考虑的是长按删除。长按,d出对话框,提示是否删除,是则删除,否则不做任何事。所以在MainActivity中可以看到长按事件的监听器。但是因为AndroID的事件分发机制,长按事件必定会触发点击事件。所以需要在ListVIEw中设置这样一个属性,才能点击事件和长按事件同时监听。
androID:descendantFocusability="blocksDescendants"
主要功能都差不多完成了。接下来就是优化App了。我设计了过渡动画,引导页,以及是否第一次启动App。是则过渡动画过渡完到引导页,引导页完才到主页。否则过渡动画过渡完则直接进入主页。还设计了引导页的切换动画,使用了nineoldandroID,保证动画在低版本手机上可显示。
优化App部分可见我另外一篇博客,传送门:Android实现过渡动画、引导页 Android判断是否第一次启动App
项目地址在:https://github.com/someonexiaole/Android
Notepad 即是。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
以上是内存溢出为你收集整理的Android记事本项目开发全部内容,希望文章能够帮你解决Android记事本项目开发所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)