当前位置: 移动技术网 > 移动技术>移动开发>Android > Android记事本项目开发

Android记事本项目开发

2019年07月24日  | 移动技术网移动技术  | 我要评论

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

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网