likes
comments
collection
share

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

作者站长头像
站长
· 阅读数 16

一、引言

欢迎回到我们的Android笔记应用开发系列!

在日常生活中,我们常常需要记录重要的想法、任务或灵感。随着智能手机的普及,将这些笔记存储在便捷的应用程序中已经成为了一种习惯。

但是,你是否曾经想过如何创建自己的笔记应用,以更好地满足个人需求,或者简单地出于好奇?

在这个教程中,我们将在上一篇文章的基础上,继续带着你一步步创建一个功能强大的 Android 笔记应用。

无需担心,即使你是一个初学者,我们将以易懂的方式解释每个步骤,让你能够轻松掌握 Android 应用开发的精髓。

我们将从数据库的创建、CRUD操作的实现,一直到精心构建用户界面,最终让你轻松掌握如何添加新笔记的功能

无论你是初学者还是有经验的开发者,都将在这里找到有趣的灵感和宝贵的知识。

现在,让我们继续踏上这个令人兴奋的 Android 开发之旅吧!

二、第一步 - 数据库创建与管理

首先,让我们创建NoteDatabase类,这将帮助我们管理笔记数据。数据库操作中的核心就是这个类。它继承自SQLiteOpenHelper,用于创建和维护数据库。

在创建NoteDatabase类时,

1. 定义4个属性:表名、内容字段、主键字段、时间字段。

代码如下:

// 定义数据库表和字段的常量
public static final String TABLE_NAME = "notes"; // 表名
public static final String CONTENT = "content"; // 内容字段
public static final String ID = "_id"; // 主键字段
public static final String TIME = "time"; // 时间字段

其中,public static final 定义了一个可以在任何地方通过类名直接访问的不可改变的常量,即 静态常量。 常用于:配置参数、常用数学常数、数据库表名、错误代码等等。

  • public 表示公开可访问
  • static 表示与类相关而非类的实例
  • final 表示值是不可更改的

2. 实现构造方法

代码如下:

// 构造方法,接受上下文参数
public NoteDatabase(Context context) {
    super(context, "notes", null, 1); // 创建数据库,指定名称和版本
}

其中,

  1. context即上下文对象,理解它的概念干啥?用就完了!
  2. super(context, "notes", null, 1): 这个部分调用了父类 SQLiteOpenHelper 的构造函数,super 表示调用父类的构造函数。

它将创建一个名为 "notes" 的数据库,它会在给定的 context 中被使用,版本号为 1。这个数据库将用于存储笔记数据。

  • context: 这是我们传递给构造函数的 Context 对象,它告诉数据库在哪个上下文中被创建和使用。

  • "notes": 这是数据库的名称,通常是一个字符串。在这里,数据库的名称被设置为 "notes"。

  • null: 这个参数通常用于传递一个自定义的游标工厂,但在这里我们不需要,所以传递 null

  • 1: 这是数据库的版本号。每当你更改数据库的结构,你需要增加版本号。这有助于数据库升级的管理。在这里,我们将数据库的版本设置为 1。

3. 执行 SQL 语句创建名为 "notes" 的数据库表格。

这个表格将用于存储我们的笔记数据,确保数据的完整性和唯一性。

// 当数据库首次创建时会调用此方法
@Override
public void onCreate(SQLiteDatabase db) {
    // 执行 SQL 语句创建名为 "notes" 的表
    db.execSQL("CREATE TABLE " + TABLE_NAME
            + "("
            + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " // 主键字段,自增长
            + CONTENT + " TEXT NOT NULL, " // 内容字段,不能为空
            + TIME + " TEXT NOT NULL)"); // 时间字段,不能为空
}

其中,

  1. db.execSQL(...): 这一行代码用于执行 SQL 语句。db 是一个 SQLiteDatabase 对象,它代表了我们的数据库。execSQL 是执行 SQL 语句的方法。

  2. "CREATE TABLE " + TABLE_NAME ...: 这是 SQL 语句的一部分,用于创建一个名为 "notes" 的表格。TABLE_NAME 是我们之前定义的一个常量,它包含了表格的名称,即 "notes"。

  3. + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, ": 这一部分定义了表格的主键。ID 是我们之前定义的常量,表示主键字段的名称。INTEGER 表示这是一个整数字段,PRIMARY KEY 表示这是主键,AUTOINCREMENT 表示这个主键字段会自动增长,每次插入一条新记录时,主键值会自动递增。

  4. + CONTENT + " TEXT NOT NULL, ": 这部分定义了内容字段,CONTENT 是我们之前定义的字段名称,TEXT 表示这是一个文本字段,NOT NULL 表示内容字段不能为空。

  5. + TIME + " TEXT NOT NULL)": 同样,这部分定义了时间字段,TIME 是字段名称,TEXT 表示这是一个文本字段,NOT NULL 表示时间字段不能为空。

4. 数据库升级

这是一个必须定义的方法,但至少可以预见的时间内将不会用到这个方法,所以不必实现。 注意:必须定义,不然编译器会报错,

// 当数据库需要升级时会调用此方法
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // 在数据库升级时的操作,此处不需要实现
}

如果你真的好奇,可以参考以下代码:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // 在数据库升级时,可以执行一系列操作,如创建新表、迁移数据等
    if (newVersion > oldVersion) {
        // 版本号增加,说明需要执行升级操作
        switch (oldVersion) {
            case 1:
                // 假设从版本1升级到版本2
                // 创建一个新表或添加新列
                db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + MODE + " INTEGER DEFAULT 1");
                // 在这里可以继续执行其他升级操作
            case 2:
                // 假设从版本2升级到版本3
                // 执行其他升级操作
            // ...
        }
    }
}

5. NoteDatabase类的代码(注释详细)如下:

package com.example.my_notes_record;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class NoteDatabase extends SQLiteOpenHelper {
    // 定义数据库表和字段的常量
    public static final String TABLE_NAME = "notes"; // 表名
    public static final String CONTENT = "content"; // 内容字段
    public static final String ID = "_id"; // 主键字段
    public static final String TIME = "time"; // 时间字段

    // 构造方法,接受上下文参数
    public NoteDatabase(Context context) {
        super(context, "notes", null, 1); // 创建数据库,指定名称和版本
    }

    // 当数据库首次创建时会调用此方法
    @Override
    public void onCreate(SQLiteDatabase db) {
        // 执行 SQL 语句创建名为 "notes" 的表
        db.execSQL("CREATE TABLE " + TABLE_NAME
                + "("
                + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " // 主键字段,自增长
                + CONTENT + " TEXT NOT NULL, " // 内容字段,不能为空
                + TIME + " TEXT NOT NULL)"); // 时间字段,不能为空
    }

    // 当数据库需要升级时会调用此方法
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // 在数据库升级时的操作,此处不需要实现
    }
}

NoteDatabase定义了笔记数据库的结构,包括内容、ID和时间字段。我们将使用它来存储和检索笔记数据。

三、第二步 - CRUD操作

接下来,我们需要一些方法来执行常见的数据库操作 - 增加、查询、更新和删除(CRUD)。我们创建了CRUD类,用于实现这些操作。

1. 必要的属性

SQLiteOpenHelper dbHandler; // SQLiteOpenHelper 实例用于处理数据库连接
SQLiteDatabase db; // SQLiteDatabase 实例用于执行数据库操作

// 定义数据库表的列名
private static final String[] columns = {
        NoteDatabase.ID,
        NoteDatabase.CONTENT,
        NoteDatabase.TIME
};

其中,

  1. SQLiteOpenHelper 是 Android 中用于管理 SQLite 数据库的类,它提供了一些方法来创建、打开和管理数据库。

  2. SQLiteDatabase 是 Android 中用于执行 SQL 操作的类,包括插入、查询、更新和删除数据等。

  3. private static final String[] columns: 这是一个字符串数组,定义了数据库表的列名。在这个数组中,包含了三个字符串元素,分别是 NoteDatabase.IDNoteDatabase.CONTENTNoteDatabase.TIME。这些元素表示了数据库表中的列名,可以在后续的操作中用于查询或操作数据库中的数据。

2. 构造方法

// 构造方法,接受上下文参数
public CRUD(Context context) {
    dbHandler = new NoteDatabase(context); // 初始化数据库处理器
}

通过这个构造方法,可以初始化数据库处理器 dbHandler,以便在后续的数据库操作中使用。

更具体地说,我们首先接受一个 Context 参数,它代表 Android 应用的运行上下文。这个上下文参数是必需的,因为它能够提供应用程序的环境信息,比如访问资源、执行数据库操作等。

然后,我们初始化了 dbHandler,这是一个 NoteDatabase 类型的实例。NoteDatabase 类继承自 SQLiteOpenHelper,用于创建和维护数据库。所以,dbHandler 就是用来处理数据库连接的“处理器”。

3. 数据库连接的打开和关闭

// 打开数据库连接
public void open() {
    db = dbHandler.getWritableDatabase(); // 获取可写的数据库连接
}

// 关闭数据库连接
public void close() {
    dbHandler.close(); // 关闭数据库处理器
}

这里没啥好说的,都是自带的库函数,这里只是包装一下。

4. 添加一条笔记记录

当我们想要添加一条笔记记录时。

首先,我们需要准备一份包含要存储的数据的清单,这个清单中包括了笔记的内容和时间信息。

随后,我们把这份数据清单交给数据库,要求它把这些数据存储起来。数据库负责将这些数据放到合适的位置,同时还会为每一条记录生成一个独特的标识,通常是一个数字。这个数字标识着这条笔记在数据库中的位置,就好像每本书都有一个独一无二的编号一样。

最后,数据库把生成的编号交还给我们,这样我们就知道了这条笔记的独特身份。

这个过程很类似于在书籍中生成一本新书的编号,以便之后可以找到它。

于是,不难写出代码如下:

// 添加一条笔记记录
public Note addNote(Note note) {
    ContentValues contentValues = new ContentValues(); // 创建一个用于存储数据的 ContentValues 对象
    contentValues.put(NoteDatabase.CONTENT, note.getContent()); // 添加内容
    contentValues.put(NoteDatabase.TIME, note.getTime()); // 添加时间
    long insertId = db.insert(NoteDatabase.TABLE_NAME, null, contentValues); // 将数据插入数据库
    note.setId(insertId); // 将插入后的 ID 设置到笔记对象中
    return note; // 返回包含新数据的笔记对象
}

其中,contentValues对象是Android提供的用于存储数据的容器。 这个对象就像一张清单,我们可以把需要存储的数据逐一添加进去。

5. 获取所有笔记记录

要获取所有笔记记录,我们首先需要向数据库查询请求。

我们需要告诉数据库我们希望从哪个表中获取数据(本文中是"notes"表),以及我们希望获取哪些列的数据(ID、内容、时间等)。

然后,数据库会返回一个包含这些数据的游标(Cursor)。

接着,我们检查游标中是否有数据。

如果有,就逐一提取每一行的数据,创建笔记对象,将数据填充到笔记对象中。

接下来再将笔记对象添加到一个列表中。

这个列表会包含所有的笔记记录。

最后,关闭游标,释放资源,返回笔记列表即可。

于是,不难写出代码如下:

// 获取所有笔记记录
public List<Note> getAllNotes() {

    Cursor cursor = db.query(
            NoteDatabase.TABLE_NAME,  // 表名
            columns,                // 要查询的列(在这里是ID、内容、时间)
            null,                   // 查询条件(null表示无特殊条件)
            null,                   // 查询条件参数(null表示无特殊条件)
            null,                   // 分组方式(null表示不分组)
            null,                   // 过滤方式(null表示不过滤)
            null                    // 排序方式(null表示不排序)
    );

    List<Note> notes = new ArrayList<>(); // 创建一个笔记列表用于存储查询结果
    if (cursor.getCount() > 0) {
        while (cursor.moveToNext()) {
            Note note = new Note(); // 创建笔记对象
            note.setId(cursor.getLong(cursor.getColumnIndex(NoteDatabase.ID))); // 设置 ID
            note.setContent(cursor.getString(cursor.getColumnIndex(NoteDatabase.CONTENT))); // 设置内容
            note.setTime(cursor.getString(cursor.getColumnIndex(NoteDatabase.TIME))); // 设置时间
            notes.add(note); // 将笔记对象添加到列表中
        }
    }
    cursor.close(); // 关闭游标
    return notes; // 返回包含所有笔记记录的列表
}

List<Note> notes = new ArrayList<>(); 这行代码创建了一个名为 notes 的列表,用于存储 Note 对象,初始化为空的 ArrayList

  • List<Note>:定义了列表类型,其中 List 是一个表示集合数据结构的接口,<Note> 指明了该列表将存储 Note 对象。

  • new ArrayList<>():创建了一个新的 ArrayList 实例,用于存储多个元素。 <Note> 表示创建一个存储 Note 对象的 ArrayListnew 关键字用于实例化新对象,() 表示创建一个空的 ArrayList,没有初始化元素。

此外,Cursor 是一个数据库查询结果的引用,它指向查询结果的第一行数据之前,可用于访问数据库查询的结果集,如检索记录的各个字段的值。这是在 Android 中处理数据库查询结果的常见方式。

6. CRUD类的代码(注释详细)如下:


package com.example.my_notes_record;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;
import java.util.List;

public class CRUD {
    SQLiteOpenHelper dbHandler; // SQLiteOpenHelper 实例用于处理数据库连接
    SQLiteDatabase db; // SQLiteDatabase 实例用于执行数据库操作
    
    // 定义数据库表的列名
    private static final String[] columns = {
            NoteDatabase.ID,
            NoteDatabase.CONTENT,
            NoteDatabase.TIME
    };

    // 构造方法,接受上下文参数
    public CRUD(Context context) {
        dbHandler = new NoteDatabase(context); // 初始化数据库处理器
    }

    // 打开数据库连接
    public void open() {
        db = dbHandler.getWritableDatabase(); // 获取可写的数据库连接
    }

    // 关闭数据库连接
    public void close() {
        dbHandler.close(); // 关闭数据库处理器
    }

    // 添加一条笔记记录
    public Note addNote(Note note) {
        ContentValues contentValues = new ContentValues(); // 创建一个用于存储数据的 ContentValues 对象
        contentValues.put(NoteDatabase.CONTENT, note.getContent()); // 添加内容
        contentValues.put(NoteDatabase.TIME, note.getTime()); // 添加时间
        long insertId = db.insert(NoteDatabase.TABLE_NAME, null, contentValues); // 将数据插入数据库
        note.setId(insertId); // 将插入后的 ID 设置到笔记对象中
        return note; // 返回包含新数据的笔记对象
    }

public List<Note> getAllNotes() {
    
    Cursor cursor = db.query(
            NoteDatabase.TABLE_NAME,  // 表名
            columns,                // 要查询的列(在这里是ID、内容、时间)
            null,                   // 查询条件(null表示无特殊条件)
            null,                   // 查询条件参数(null表示无特殊条件)
            null,                   // 分组方式(null表示不分组)
            null,                   // 过滤方式(null表示不过滤)
            null                    // 排序方式(null表示不排序)
    );

    List<Note> notes = new ArrayList<>(); // 创建一个笔记列表用于存储查询结果
    if (cursor.getCount() > 0) {
        while (cursor.moveToNext()) {
            Note note = new Note(); // 创建笔记对象
            note.setId(cursor.getLong(cursor.getColumnIndex(NoteDatabase.ID))); // 设置 ID
            note.setContent(cursor.getString(cursor.getColumnIndex(NoteDatabase.CONTENT))); // 设置内容
            note.setTime(cursor.getString(cursor.getColumnIndex(NoteDatabase.TIME))); // 设置时间
            notes.add(note); // 将笔记对象添加到列表中
        }
    }
    cursor.close(); // 关闭游标
    return notes; // 返回包含所有笔记记录的列表
    }

}

CRUD类包含了一系列方法,用于执行数据库操作。我们可以添加笔记、获取所有笔记等。

四、第三步 - ListView

我们需要将activity_main.xml中的TextView组件替换为ListView组件,具体如下:

    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="8dp"
        android:dividerHeight="8dp">

    </ListView>

ListView 在 Android 中用于显示垂直滚动的可滚动列表,通常用于展示大量数据,以确保用户可以滚动查看所有数据,而不必在屏幕上放置所有内容。

选择使用ListView组件关键在于其四大优势:

  1. 滚动能力ListView 允许用户在有限的屏幕空间内滚动查看大量项目,以便浏览长列表或数据集。

  2. 节省空间:相对于将所有项目一次性放在屏幕上,ListView 只会渲染并占用屏幕空间的一部分,这有助于节省屏幕空间,同时使应用更具交互性。

  3. 性能优化ListView 采用适用于大型数据集的数据适配器模式,只加载当前可见区域的数据,从而提高性能。

  4. 动态数据ListView 可以轻松地与动态数据集结合使用,以实时更新列表内容。

如欲了解更多信息,这篇名叫Android List View的文档也许能满足你。

五、第四步 - 主页(MainActivity)

现在,让我们来看看应用的主要界面 - MainActivity。这是我们的笔记应用的入口,也是笔记列表的显示和添加点。在这里,我们将与数据库交互,加载和显示笔记。

前面的文章中已经写出了部分代码,下面将主要针对修改或添加的地方加以解释。

1. 属性

比起原先的属性,在保留FloatingActionButton类的同时增添了多个属性。

// 声明类的成员变量
    private Context context = this; // 上下文对象,用于数据库操作
    private NoteDatabase dbHelper; // 数据库帮助类
    private NoteAdapter adapter; // 笔记适配器
    private List<Note> noteList = new ArrayList<>(); // 笔记列表
    private FloatingActionButton btn; // 悬浮按钮
    private ListView lv; // 列表视图

    // 定义一个 ActivityResultLauncher,用于处理其他活动的结果
    private ActivityResultLauncher<Intent> someActivityResultLauncher;
  1. context 是一个上下文对象,用于进行数据库操作。在这里,它引用了当前 Activity 的上下文。

  2. dbHelper 是一个数据库帮助类,用于管理数据库的创建和升级。

  3. adapter 是一个笔记适配器,用于在用户界面中显示笔记数据。

  4. noteList 是一个笔记列表,初始化为空,用于存储笔记对象。

  5. btn 是一个悬浮按钮,通常用于触发用户界面上的某些操作。

  6. lv 是一个列表视图,用于显示数据列表,例如显示笔记的列表。

  7. someActivityResultLauncher 是用于处理其他活动返回的数据或结果的工具。

2. onCreate方法

protected void onCreate(Bundle savedInstanceState) someActivityResultLauncher = registerForActivityResult 之间添加了大量代码,具体如下:

    super.onCreate(savedInstanceState);
    //调用父类的 onCreate 方法,用于执行一些初始化操作
    //savedInstanceState 参数用于恢复之前的状态

    setContentView(R.layout.activity_main);//设置当前 Activity 的布局
    
    btn = findViewById(R.id.fab); // 悬浮按钮


    //以下是新添的代码

    lv = findViewById(R.id.lv); // 列表视图,用于显示数据列表

    adapter = new NoteAdapter(getApplicationContext(), noteList);//初始化一个笔记适配器,并将应用的上下文对象和笔记列表传递给适配器

    refreshListView(); // 刷新笔记列表
    
    lv.setAdapter(adapter); // 将适配器与列表视图关联,从而显示笔记列表中的数据在界面上

if (data != null){...}中(...部分)替换为下面这段代码:

    // 从 EditActivity 返回的内容和时间
    String content = data.getStringExtra("content");
    String time = data.getStringExtra("time");
    Note note = new Note(content, time); // 创建笔记对象

    // 打开数据库连接,将笔记添加到数据库
    CRUD op = new CRUD(context);
    op.open();
    op.addNote(note);
    op.close(); // 关闭数据库连接

    refreshListView(); // 刷新笔记列表

3. 刷新笔记列表

要想刷新笔记列表。

首先我们需要确保数据库连接已经打开。

接下来,我们需要清空当前的笔记列表,因为我们要用最新的数据替代它。

然后,我们从数据库中获取所有的笔记数据,并将它们添加到列表中。

最后,我们关闭数据库连接,以释放资源。

刷新列表时,我们通知适配器,数据已经更改,需要刷新列表视图,以确保用户界面上显示的笔记列表是最新的。

于是不难写出代码如下:

    // 刷新笔记列表
    public void refreshListView() {
        // 创建数据库操作对象,打开数据库连接
        CRUD op = new CRUD(context);
        op.open();

        if (noteList.size() > 0) noteList.clear(); // 清空笔记列表
        noteList.addAll(op.getAllNotes()); // 获取数据库中所有笔记
        op.close(); // 关闭数据库连接

        adapter.notifyDataSetChanged(); // 通知适配器数据已更改,刷新列表视图
    }

4. MainActivity的代码(注释详细)如下:

package com.example.my_notes_record;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.ArrayList;
import java.util.List;


// 创建名为 "MainActivity" 的主活动类
public class MainActivity extends AppCompatActivity {

    private Context context = this; // 上下文对象,用于数据库操作
    private NoteDatabase dbHelper; // 数据库帮助类
    private NoteAdapter adapter; // 笔记适配器
    private List<Note> noteList = new ArrayList<>(); // 笔记列表
    private FloatingActionButton btn; // 悬浮按钮
    private ListView lv; // 列表视图

    // 定义一个 ActivityResultLauncher,用于处理其他活动的结果
    private ActivityResultLauncher<Intent> someActivityResultLauncher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        
        super.onCreate(savedInstanceState);
        //调用父类的 onCreate 方法,用于执行一些初始化操作
        //savedInstanceState 参数用于恢复之前的状态

        setContentView(R.layout.activity_main);//设置当前 Activity 的布局
        
        btn = findViewById(R.id.fab); // 悬浮按钮

        lv = findViewById(R.id.lv); // 列表视图,用于显示数据列表

        adapter = new NoteAdapter(getApplicationContext(), noteList);//初始化一个笔记适配器,并将应用的上下文对象和笔记列表传递给适配器

        refreshListView(); // 刷新笔记列表

        lv.setAdapter(adapter); // 将适配器与列表视图关联,从而显示笔记列表中的数据在界面上

        // 初始化 ActivityResultLauncher,用于处理启动其他活动的结果
        someActivityResultLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK) {
                        Intent data = result.getData();
                        if (data != null) {
                            // 从 EditActivity 返回的内容和时间
                            String content = data.getStringExtra("content");
                            String time = data.getStringExtra("time");
                            Note note = new Note(content, time); // 创建笔记对象

                            // 打开数据库连接,将笔记添加到数据库
                            CRUD op = new CRUD(context);
                            op.open();
                            op.addNote(note);
                            op.close(); // 关闭数据库连接

                            refreshListView(); // 刷新笔记列表
                        }
                    }
                }
        );

        // 设置悬浮按钮的点击事件监听器
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 启动 EditActivity 并等待结果
                Intent intent = new Intent(MainActivity.this, EditActivity.class);
                someActivityResultLauncher.launch(intent);
            }
        });
    }

    // 刷新笔记列表
    public void refreshListView() {
        // 创建数据库操作对象,打开数据库连接
        CRUD op = new CRUD(context);
        op.open();

        if (noteList.size() > 0) noteList.clear(); // 清空笔记列表
        noteList.addAll(op.getAllNotes()); // 获取数据库中所有笔记
        op.close(); // 关闭数据库连接

        adapter.notifyDataSetChanged(); // 通知适配器数据已更改,刷新列表视图
    }
}

六、第五步 - 笔记列表(EditActivity)

最后,让我们看一下编辑笔记的界面 - EditActivity。这是用户输入笔记内容的地方,我们还会将时间自动添加到笔记中。

前面的文章中已经写出了部分代码,下面将主要针对修改或添加的地方加以解释。

1. 新添两个属性:contenttime

private String content; // 声明用于存储笔记内容的变量
private String time; // 声明用于存储笔记时间的变量

2. 为意图添加额外数据

else if (keyCode == KeyEvent.KEYCODE_BACK) {...}中 将intent.putExtra("input", et.getText().toString()); 替换为

intent.putExtra("content", et.getText().toString()); // 将编辑框中的文本内容放入意图中
intent.putExtra("time", dateToStringing()); // 将当前时间放入意图中

3. 指定时间显示格式

// 将当前时间格式化为字符串
public String dateToStringing(){
    Date date = new Date(); // 获取当前日期和时间
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 创建日期格式化器
    return simpleDateFormat.format(date); // 格式化日期并返回字符串
}

4. EditActivity的代码(注释详细)如下:

package com.example.my_notes_record;

import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.widget.EditText;

import androidx.appcompat.app.AppCompatActivity;

import java.text.SimpleDateFormat;
import java.util.Date;

public class EditActivity extends AppCompatActivity{

    private String content; // 声明用于存储笔记内容的变量
    private String time; // 声明用于存储笔记时间的变量

    EditText et; // 声明文本编辑框

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.edit_layout); // 设置视图为 "edit_layout"
        et = findViewById(R.id.et); // 从布局文件中获取文本编辑框
    }

    // 处理按键事件
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_HOME) {
            return true; // 如果按下 HOME 键,返回 true,表示事件已处理
        } else if (keyCode == KeyEvent.KEYCODE_BACK) {
            Intent intent = new Intent(); // 创建一个新意图
            intent.putExtra("content", et.getText().toString()); // 将编辑框中的文本内容放入意图中
            intent.putExtra("time", dateToString()); // 将当前时间放入意图中
            setResult(RESULT_OK, intent); // 设置结果为 OK,并附带意图
            finish(); // 结束当前活动
            return true; // 返回 true,表示事件已处理
        }
        return super.onKeyDown(keyCode, event); // 如果按键不是 HOME 或 BACK,使用默认处理
    }

    // 将当前时间格式化为字符串
    public String dateToString(){
        Date date = new Date(); // 获取当前日期和时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 创建日期格式化器
        return simpleDateFormat.format(date); // 格式化日期并返回字符串
    }
}

七、结果演示

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

轻松上手:<Android Studio笔记应用开发>(二)大功告成!添加新笔记!

八、结语

太棒了,现在我们可以轻松地添加和展示笔记了。

在下一篇文章中,我们将实现笔记的可查看、可编辑等功能。

敬请关注!

持续爆肝更新中...🫡🫡🫡

求点赞👍求关注🤗求转发😍