任务6.1:实现笔记本(1)

2018-05-07  本文已影响0人  jingz课程

设计思路

笔记本与笔记是一对多的关系:

1. 数据库设计

首先,我们需要为笔记本创建新的表,将其命名为notebook。我们简单的将其设计为具有以下字段:

2. 数据库修改

打开前面章节中创建的NoteDAO类,找到其中的内部类NoteDbHelper,修改它的onCreate(),修改note表创建语句,在最后增加notebookId列,并添加创建notebook表的语句:

        @Override
        public void onCreate(SQLiteDatabase db) {
            // 创建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)");

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

出现了三个新的常量,分别是笔记本表的表名常量TABLE_NOTEBOOK,以及笔记本名字对应的列名常量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";
}

另外,根据对笔记表的修改,我们应当相应的修改Note类,增加notebookId属性以及对应的访问方法。打开Note类,增加以下内容,其它旧有部分保持不变:

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;
    }
}

可以看到,我们还增加了一个构造方法,将notebookId的初始化包含进去。原来已有的构造方法保持不变。

运行代码之前,将原来版本的App从模拟器或者手机中删除。原因是,数据库结构变更并不会自动触发升级操作。而数据库升级操作相对复杂,此处我们先不考虑,只是简单的卸载后重新运行程序。这样做的弊端是,原来已有的数据全部丢失。但是对于目前阶段,我们的数据主要是测试数据,因此影响不大。

接下来,由于数据模型发生变化,我们的数据访问方法也要进行相应的修改。再次打开NoteDAO类,依次修改如下方法:

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写入数据库
        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);
        ...
    }

运行代码,应用原有功能应当保持不变。

2. 创建笔记本列表页面

用ActionBar图标按钮来作为笔记本列表入口:

device-2018-05-07-180910.png

在点击右上角笔记本按钮后,打开一个新的activity,我们将其命名为NotebooksActivity。在这个activity中,完成以下功能:

在我们的项目包名上右键选择“New -> Activity -> Empty Activity”,在弹出的对话框中填写名称并确认:

点击“Finish”,NotebooksActivity.java文件以及对应的布局文件自动创建完毕。

将NotebooksActivity的标题设置为“笔记本”(还记得怎么做吗?):

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

现在打开全部笔记页面,添加ActionBar上的笔记本按钮。打开NoteListActivity类,添加菜单处理相关的两个方法:

    @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菜单项必然也不存在,编辑界面会提示错误:

下面我们创建它们。在res目录下找到menu目录,里面已经有我们之前为新建笔记页面创建的菜单文件。我们现在新建一个名为menu_note_list.xml的新菜单文件,方法是右键单击menu文件夹,在弹出的菜单中选择“New -> Menu resource file”,在弹出的对话框中输入文件名:

点击OK完成,则创建好了空菜单文件:

打开编辑,为其中添加如下的菜单项:

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

其中:

ic_notebook.png

下载上面的图片,放到你的res/drawable-xxhdpi文件夹下即可。

现在我们实现笔记本按钮的操作,也就是启动我们刚才创建的笔记本列表页面。但是,这回不是简单的启动,而是要在笔记本列表中选择某个笔记本后将笔记本的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()多了一个参数“1”,这代表这次操作的请求码,据此在读取返回结果时判断来自哪个activity。至于如何处理返回结果,我们随后再讨论,现在简单的看一下启动笔记本列表页面的效果:

上一篇 下一篇

猜你喜欢

热点阅读