欢迎来到代码驿站!

Android代码

当前位置:首页 > 移动开发 > Android代码

Android记事本项目开发

时间:2021-07-22 07:46:24|栏目:Android代码|点击:

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

上一篇:Android中Fragment的加载方式与数据通信详解

栏    目:Android代码

下一篇:Android获取验证码倒计时实现代码

本文标题:Android记事本项目开发

本文地址:http://www.codeinn.net/misctech/160098.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有