为了创建一个简单的Android笔记应用,前文已经成功实现了以下主要功能:

  1. 笔记的展示: 主活动(MainActivity)中通过一个列表视图(ListView)展示了所有笔记的内容和创建时间。
  2. 笔记的添加: 用户通过悬浮按钮(FloatingActionButton)可以添加新的笔记,进入编辑页面(EditActivity),并在该页面输入笔记内容后保存。
  3. 笔记的保存和显示: 新添加的笔记会保存在 SQLite 数据库中,主活动在每次启动时从数据库读取笔记列表,并通过适配器(NoteAdapter)将笔记显示在列表视图中。
  4. 笔记的点击编辑: 用户可以点击笔记列表中的项,进入编辑页面,编辑该笔记的内容。
  5. 笔记长按可删除: 用户可以长按笔记列表中的项,弹出提示框后可删除笔记或取消。

III. SearchView - 搜索视图

SearchViewAndroid 应用中用于实现搜索功能的一个控件,我们可以通过它为我们的应用添加搜索功能。

此外我们也可以很容易地集成到应用的 ActionBarToolbar 中,提供用户友好的搜索体验。
(关于ActionBarToolbar 。由于考虑到本文的行文结构和读者的接受度,将在后续文章深入讲解并应用到我们的笔记应用中,本文将不多涉猎。)

1. 搜索视图的添加

SearchView 可以作为一个独立的组件添加到布局文件中,或者作为菜单项集成到应用的 ActionBarToolbar 中。这里,我们将其直接添加到activity_main.xml布局文件中,使其在应用的主界面上可见。

<SearchView
    android:id="@+id/searchView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

2. 事件监听器的设置

import android.widget.SearchView;
// ...

private SearchView searchView; // 搜索视图
// ...

searchView = findViewById(R.id.searchView); // 搜索视图 用于在应用程序中提供搜索功能
// ...


// 设置监听器
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override  // 查询文本提交
            public boolean onQueryTextSubmit(String query) {
                // 处理搜索提交(如果需要的话) 这里显然不需要
                return false; // 不处理搜索提交 , 将依赖系统提供的默认行为(关闭键盘)
            }

            @Override // 只要“SearchView”中的文本发生更改,即当用户在搜索框中键入或删除字符时,就会调用此方法。
            public boolean onQueryTextChange(String newText) {
                // 处理文本更改时的搜索
                filterNotes(newText);
                return true; // 完全处理了文本更改时的搜索 ,并将不采取默认行为
                }
            }
        );

其中,

  • onQueryTextSubmit(String query): 当用户确认搜索(例如,通过键盘上的搜索按钮)时调用。这里可以处理搜索逻辑,比如根据查询词query搜索数据。在本例中,我们选择不处理提交事件,返回false以保持搜索视图可见并保持键盘打开状态。
  • onQueryTextChange(String newText): 当搜索框内文本变化时调用,无论是添加还是删除字符。这允许实现即时搜索或过滤功能,提升用户体验。在filterNotes(newText)方法中,我们根据用户输入的新文本newText来过滤笔记列表。返回true表示该事件已被处理,不需要默认行为(如关闭键盘)。

3. 查找逻辑的实现 - filterNotes() 方法

过滤笔记

private void filterNotes(String query) {
    // 创建一个新的笔记列表,用于存储过滤后的笔记
    List<Note> filteredList = new ArrayList<>();

    // 遍历原始笔记列表
    for (Note note : noteList) {
        // 判断笔记内容是否包含用户输入的查询条件(不区分大小写)
        if (note.getContent().toLowerCase().contains(query.toLowerCase())) {
            // 笔记内容匹配查询条件,将笔记添加到过滤后的列表中
            filteredList.add(note);
        }
    }

    // 更新适配器的笔记列表为过滤后的列表
    adapter.setNoteList(filteredList);

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

    // 刷新整个笔记列表视图
    refreshListView();
}

实现步骤详解:

  1. 创建过滤后的笔记列表:方法首先创建一个新的ArrayList,用于存储匹配查询条件的笔记。这一步确保了我们不会修改原始的笔记列表,从而保持了数据的完整性和稳定性。
  2. 遍历原始笔记列表:通过遍历noteList,我们可以逐一检查每个笔记是否满足搜索条件。这一步是实现搜索功能的核心。
  3. 判断笔记内容与查询条件的匹配情况:使用String类的toLowerCase()方法将笔记内容和查询条件都转换为小写,这样做可以实现不区分大小写的搜索。然后使用contains()方法检查笔记内容是否包含查询字符串。如果包含,就意味着这个笔记项与搜索条件匹配。
  4. 更新适配器的笔记列表:一旦确定了哪些笔记项满足搜索条件,就需要更新NoteAdapter的笔记列表,使其仅包含这些过滤后的项。这一步通过调用NoteAdapter中的setNoteList()方法实现。
  5. 通知数据变更:调用adapter.notifyDataSetChanged()方法通知适配器,数据集已经改变,这将触发界面的更新,从而显示过滤后的笔记列表。
  6. 刷新列表视图:最后,调用refreshListView()方法可以确保笔记列表视图完全根据最新的过滤结果更新。

NoteAdapter中添加setNoteList方法

public void setNoteList(List<Note> noteList) {
    this.noteList = noteList;
}