欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android记事本项目开发

程序员文章站 2022-03-22 23:36:57
写了一个android记事本小程序,现在记录一下。 考虑到是记事本小程序,记录的内容只有文字,而且内容不会太长,所以选择使用sqlite数据库,数据存放在用户的手机上。...

写了一个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 即是。

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