任務(wù)6.1:實現(xiàn)筆記本(1)

設(shè)計思路

筆記本與筆記是一對多的關(guān)系:

  • 每條筆記屬于一個筆記本
  • 一個筆記本包含多條筆記

1. 數(shù)據(jù)庫設(shè)計

首先,我們需要為筆記本創(chuàng)建新的表,將其命名為notebook。我們簡單的將其設(shè)計為具有以下字段:

  • id: 一個筆記本的唯一id
  • name: 筆記本的名字
    其次,我們要為筆記表(note)增加與筆記本表的關(guān)聯(lián)。則在創(chuàng)建note表時增加一列notebookId,即某條筆記對應(yīng)的筆記本的id

2. 數(shù)據(jù)庫修改

打開前面章節(jié)中創(chuàng)建的NoteDAO類,找到其中的內(nèi)部類NoteDbHelper,修改它的onCreate(),修改note表創(chuàng)建語句,在最后增加notebookId列,并添加創(chuàng)建notebook表的語句:

        @Override
        public void onCreate(SQLiteDatabase db) {
            // 創(chuàng)建note表
            db.execSQL("CREATE TABLE " + TABLE_NOTE + "(" +
                COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COL_TITLE + " TEXT, " +
                COL_CONTENT + " TEXT, " +
                COL_CREATE_TIME + " INTEGER, " +
                COL_NOTEBOOK_ID + " INTEGER)");

            // 創(chuàng)建notebook表
            db.execSQL("CREATE TABLE " + TABLE_NOTEBOOK + "(" +
                    COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    COL_NOTEBOOK_NAME + " TEXT)");
        }

出現(xiàn)了三個新的常量,分別是筆記本表的表名常量TABLE_NOTEBOOK,以及筆記本名字對應(yīng)的列名常量COL_NOTEBOOK_NAME。打開與NoteDAO類同一包下的Constants類,在末尾添加這兩個常量:

public class Constants {
    ...
    public static final String COL_NOTEBOOK_ID = "notebookId";
    public static final String TABLE_NOTEBOOK = "notebook";
    public static final String COL_NOTEBOOK_NAME= "name";
}

另外,根據(jù)對筆記表的修改,我們應(yīng)當(dāng)相應(yīng)的修改Note類,增加notebookId屬性以及對應(yīng)的訪問方法。打開Note類,增加以下內(nèi)容,其它舊有部分保持不變:

public class Note {
    ...

    /**
     * 所屬的筆記本的id
     */
    private long notebookId;

    ...

    public Note(long id, String title, String content, long createTim, long notebookId) {
        this.id = id;
        this.title = title;
        this.content = content;
        this.createTime = createTime;
        this.notebookId = notebookId;
    }

    ...

    public long getNotebookId() {
        return notebookId;
    }

    public void setNotebookId(long noteId) {
        notebookId = notebookId;
    }
}

可以看到,我們還增加了一個構(gòu)造方法,將notebookId的初始化包含進(jìn)去。原來已有的構(gòu)造方法保持不變。

運(yùn)行代碼之前,將原來版本的App從模擬器或者手機(jī)中刪除。原因是,數(shù)據(jù)庫結(jié)構(gòu)變更并不會自動觸發(fā)升級操作。而數(shù)據(jù)庫升級操作相對復(fù)雜,此處我們先不考慮,只是簡單的卸載后重新運(yùn)行程序。這樣做的弊端是,原來已有的數(shù)據(jù)全部丟失。但是對于目前階段,我們的數(shù)據(jù)主要是測試數(shù)據(jù),因此影響不大。

接下來,由于數(shù)據(jù)模型發(fā)生變化,我們的數(shù)據(jù)訪問方法也要進(jìn)行相應(yīng)的修改。再次打開NoteDAO類,依次修改如下方法:

  • insertNote()
  • queryNoteById()
  • queryAllNotes()

insertNote()

在向note表插入筆記時,增加代碼以寫入notebookId屬性:

    public Note insertNote(Note note) {
        ...
        ContentValues values = new ContentValues();
        values.put(COL_TITLE, note.getTitle());
        values.put(COL_CONTENT, note.getContent());
        values.put(COL_CREATE_TIME, note.getCreateTime());

        // 將notebookId寫入數(shù)據(jù)庫
        values.put(COL_NOTEBOOK_ID, note.getNotebookId());
        ...
    }

queryNoteById()

    public Note queryNoteById(long id) {
        ...
        
                    String title = cursor.getString(1);
                    String content = cursor.getString(2);

                    // 讀取notebookId記錄
                    long notebookId = cursor.getLong(4);
                    Note note = new Note(id, title, content, createTime, notebookId);
                    return note;
       ...
    }

queryAllNotes()

    public List<Note> queryAllNotes() {
        ...
                    long id = cursor.getLong(0);
                    String title = cursor.getString(1);
                    String content = cursor.getString(2);
                    long createTime = cursor.getLong(3);

                    // 讀取notebookId
                    long notebookId = cursor.getLong(4);
                    Note note = new Note(id, title, content, createTime, notebookId);
                    notes.add(note);
        ...
    }

運(yùn)行代碼,應(yīng)用原有功能應(yīng)當(dāng)保持不變。

2. 創(chuàng)建筆記本列表頁面

用ActionBar圖標(biāo)按鈕來作為筆記本列表入口:

device-2018-05-07-180910.png

在點擊右上角筆記本按鈕后,打開一個新的activity,我們將其命名為NotebooksActivity。在這個activity中,完成以下功能:

  • 展示全部筆記本
  • 創(chuàng)建新的筆記本
  • 選擇筆記本,并向調(diào)用NotebooksActivity的上一級activity返回對應(yīng)的筆記本ID

在我們的項目包名上右鍵選擇“New -> Activity -> Empty Activity”,在彈出的對話框中填寫名稱并確認(rèn):

點擊“Finish”,NotebooksActivity.java文件以及對應(yīng)的布局文件自動創(chuàng)建完畢。

將NotebooksActivity的標(biāo)題設(shè)置為“筆記本”(還記得怎么做嗎?):

        <activity
            android:name=".NotebooksActivity"
            android:label="@string/notebook"/>

現(xiàn)在打開全部筆記頁面,添加ActionBar上的筆記本按鈕。打開NoteListActivity類,添加菜單處理相關(guān)的兩個方法:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater menuInflater = getMenuInflater();
        menuInflater.inflate(R.menu.menu_note_list, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_item_notebook:

                return true;
        }
        return super.onOptionsItemSelected(item);
    }

此時,菜單資源文件menu_note_list.xml并不存在,menu_item_notebook菜單項必然也不存在,編輯界面會提示錯誤:

下面我們創(chuàng)建它們。在res目錄下找到menu目錄,里面已經(jīng)有我們之前為新建筆記頁面創(chuàng)建的菜單文件。我們現(xiàn)在新建一個名為menu_note_list.xml的新菜單文件,方法是右鍵單擊menu文件夾,在彈出的菜單中選擇“New -> Menu resource file”,在彈出的對話框中輸入文件名:

點擊OK完成,則創(chuàng)建好了空菜單文件:

打開編輯,為其中添加如下的菜單項:

    <item
        android:id="@+id/menu_item_notebook"
        android:title="@string/notebook"
        android:icon="@drawable/ic_notebook"
        app:showAsAction="always"/>

其中:

  • 菜單項id為menu_item_notebook
  • 菜單項文字為“筆記本”字符串
  • “app:showAsAction”屬性表示將菜單項顯示為圖標(biāo)按鈕
  • “android:icon”屬性是對應(yīng)的圖標(biāo),設(shè)置為“@drawable/ic_notebook”
ic_notebook.png

下載上面的圖片,放到你的res/drawable-xxhdpi文件夾下即可。

現(xiàn)在我們實現(xiàn)筆記本按鈕的操作,也就是啟動我們剛才創(chuàng)建的筆記本列表頁面。但是,這回不是簡單的啟動,而是要在筆記本列表中選擇某個筆記本后將筆記本的id返回回來,于是,要用startActivityForResult()方法代替startActivity()方法來啟動筆記本列表頁面。
在onOptionsItemSelected()方法中編寫代碼如下:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_item_notebook:
                // 添加如下代碼:
                Intent intent = new Intent(this, NotebooksActivity.class);
                startActivityForResult(intent, 1);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

可以看到,startActivityForResult()多了一個參數(shù)“1”,這代表這次操作的請求碼,據(jù)此在讀取返回結(jié)果時判斷來自哪個activity。至于如何處理返回結(jié)果,我們隨后再討論,現(xiàn)在簡單的看一下啟動筆記本列表頁面的效果:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 3.1. 介紹 現(xiàn)在,您已經(jīng)安裝了Wireshark并有可能熱衷于開始捕捉您的第一個數(shù)據(jù)包。在接下來的章節(jié)中,我們...
    wwyyzz閱讀 1,494評論 0 1
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,181評論 25 708
  • ¥開啟¥ 【iAPP實現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 7,362評論 0 17
  • 回首頁 第一部分 Drupal簡介 Drupal overview A tour of Drupal fundam...
    王乂閱讀 2,226評論 0 9
  • 你把思想外套脫去 急于展示思想的肉體 我看到的是你似火的唇 我知道它柔軟,想要親吻 那不只是本能 更是我要的印證 ...
    長耳當(dāng)聽閱讀 211評論 0 0

友情鏈接更多精彩內(nèi)容