侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 129784 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

Android记事本项目开发

2023-06-03 星期六 / 0 评论 / 0 点赞 / 37 阅读 / 32096 字

写了一个Android记事本小程序,现在记录一下。考虑到是记事本小程序,记录的内容只有文字,而且内容不会太长,所以选择使用SQLite数据库,数据存放在用户的手机上。牵涉到数据库,那自然是一个实体。先设计实体数据表:DB

写了一个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", null, values);     }   }    public List<Note> loadNotes(){     List<Note> noteList = new ArrayList<Note>();     /**      * 先按时间降序排列,再按id降序排列      */     Cursor cursor = db.query("Note",null,null,null,null,null,"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",null,"id = " + id,null,null,null,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","id = " + id,null);   }    public void deleteAllNote(){     db.delete("Note", null, 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, int i, 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, View view, 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,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,如果有内容,则弹出对话框提示用户是否保存,是则保存,否则不保存,退出当前活动。

接下来是查看或修改一条记事本了,布局我是直接复用新建记事本的布局。因为没有区别 - -

接下来是查看或修改一条记事本的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,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,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("确定", new DialogInterface.OnClickListener() {              @Override             public void onClick(DialogInterface dialog, int which) {               new UpdateAsyncTask().execute();               finish();             }           })           .setNegativeButton("取消", new DialogInterface.OnClickListener() {             @Override             public void onClick(DialogInterface dialog, 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,Void> {    private NoteDB noteDB;    public DeleteAsyncTask(NoteDB noteDB) {     this.noteDB = noteDB;   }    @Override   protected Void doInBackground(Integer... params) {     noteDB.deleteById(params[0]);     return null;   }  } 
.

接下来是CRUD的最后一项,删除数据了,在主页的时候,我设计的是单击进入该条记事本,去查看或修改这一条记事本,然后我考虑的是长按删除。长按,弹出对话框,提示是否删除,是则删除,否则不做任何事。所以在MainActivity中可以看到长按事件的监听器。但是因为Android的事件分发机制,长按事件必定会触发点击事件。所以需要在ListView中设置这样一个属性,才能点击事件和长按事件同时监听。
android:descendantFocusability="blocksDescendants"

主要功能都差不多完成了。接下来就是优化App了。我设计了过渡动画,引导页,以及是否第一次启动App。是则过渡动画过渡完到引导页,引导页完才到主页。否则过渡动画过渡完则直接进入主页。还设计了引导页的切换动画,使用了nineoldandroid,保证动画在低版本手机上可显示。

优化App部分可见我另外一篇博客,传送门:Android实现过渡动画、引导页 Android判断是否第一次启动App

项目地址在:https://github.com/someonexiaole/Android
Notepad 即是。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持..。

广告 广告

评论区