From 554d5ec8e9ad41d2685f0875d9585183199d53b0 Mon Sep 17 00:00:00 2001 From: chroe <454604461@qq.com> Date: Fri, 30 Jan 2026 17:11:13 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BE=A7=E8=BE=B9=E6=A0=8F?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9=E6=98=BE=E7=A4=BA=E6=96=B9=E5=BC=8F=EF=BC=8C=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E5=A4=9A=E7=BA=A7=E6=96=87=E4=BB=B6=E5=A4=B9=E7=9A=84?= =?UTF-8?q?=E9=80=BB=E8=BE=91=EF=BC=8C=E5=AE=8C=E5=96=84=E5=A4=9A=E7=BA=A7?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=A4=B9=E5=92=8C=E4=BE=BF=E7=AD=BE=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E6=98=BE=E7=8E=B0=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9C=A8=E4=BE=A7=E8=BE=B9=E6=A0=8F=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=96=87=E4=BB=B6=E5=A4=B9=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/net/micode/notes/tool/DataUtils.java | 84 +- .../micode/notes/ui/NotesListActivity.java | 784 +++++++++++++++--- .../net/micode/notes/ui/SidebarAdapter.java | 142 ++++ src/main/res/drawable/count_badge.xml | 10 + src/main/res/drawable/ic_folder_add.xml | 9 + .../res/drawable/ic_format_color_bold.jpg | Bin 0 -> 1696 bytes .../res/drawable/ic_format_color_bold.png | Bin 733 -> 0 bytes .../res/drawable/ic_format_color_fill.jpg | Bin 0 -> 2337 bytes .../res/drawable/ic_format_color_fill.png | Bin 848 -> 0 bytes .../res/drawable/ic_format_color_text.jpg | Bin 0 -> 2099 bytes .../res/drawable/ic_format_color_text.png | Bin 726 -> 0 bytes src/main/res/drawable/ic_format_italic.jpg | Bin 0 -> 1717 bytes src/main/res/drawable/ic_format_italic.png | Bin 614 -> 0 bytes .../res/drawable/ic_format_underlined.jpg | Bin 0 -> 1779 bytes .../res/drawable/ic_format_underlined.png | Bin 597 -> 0 bytes src/main/res/layout/note_list.xml | 336 ++++---- src/main/res/layout/sidebar_item.xml | 32 + src/main/res/layout/sidebar_layout.xml | 155 ++++ src/main/res/values/colors.xml | 2 + src/main/res/values/strings.xml | 1 + 20 files changed, 1293 insertions(+), 262 deletions(-) create mode 100644 src/main/java/net/micode/notes/ui/SidebarAdapter.java create mode 100644 src/main/res/drawable/count_badge.xml create mode 100644 src/main/res/drawable/ic_folder_add.xml create mode 100644 src/main/res/drawable/ic_format_color_bold.jpg delete mode 100644 src/main/res/drawable/ic_format_color_bold.png create mode 100644 src/main/res/drawable/ic_format_color_fill.jpg delete mode 100644 src/main/res/drawable/ic_format_color_fill.png create mode 100644 src/main/res/drawable/ic_format_color_text.jpg delete mode 100644 src/main/res/drawable/ic_format_color_text.png create mode 100644 src/main/res/drawable/ic_format_italic.jpg delete mode 100644 src/main/res/drawable/ic_format_italic.png create mode 100644 src/main/res/drawable/ic_format_underlined.jpg delete mode 100644 src/main/res/drawable/ic_format_underlined.png create mode 100644 src/main/res/layout/sidebar_item.xml create mode 100644 src/main/res/layout/sidebar_layout.xml diff --git a/src/main/java/net/micode/notes/tool/DataUtils.java b/src/main/java/net/micode/notes/tool/DataUtils.java index 82e8d10..42b64f7 100644 --- a/src/main/java/net/micode/notes/tool/DataUtils.java +++ b/src/main/java/net/micode/notes/tool/DataUtils.java @@ -131,21 +131,33 @@ public class DataUtils { } // 检查目标ID是否是一个文件夹(TYPE_FOLDER或TYPE_SYSTEM) - Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, folderId), - new String[] { NoteColumns.TYPE }, - null, - null, - null); - boolean isFolder = false; - if (cursor != null) { - if (cursor.moveToFirst()) { - int type = cursor.getInt(0); - if (type == Notes.TYPE_FOLDER || type == Notes.TYPE_SYSTEM) { - isFolder = true; + + // 特殊处理系统文件夹ID,它们是逻辑ID,不是实际的数据库记录ID + if (folderId == Notes.ID_ROOT_FOLDER || + folderId == Notes.ID_TEMPARAY_FOLDER || + folderId == Notes.ID_CALL_RECORD_FOLDER || + folderId == Notes.ID_TRASH_FOLER || + folderId == Notes.ID_PRIVACY_SPACE_FOLDER) { + isFolder = true; + Log.d(TAG, "Target is a system folder: " + folderId); + } else { + // 对于非系统文件夹,查询数据库验证 + Cursor cursor = resolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, folderId), + new String[] { NoteColumns.TYPE }, + null, + null, + null); + + if (cursor != null) { + if (cursor.moveToFirst()) { + int type = cursor.getInt(0); + if (type == Notes.TYPE_FOLDER || type == Notes.TYPE_SYSTEM) { + isFolder = true; + } } + cursor.close(); } - cursor.close(); } if (!isFolder) { @@ -456,4 +468,52 @@ public class DataUtils { } return snippet; } + + /** + * 获取指定文件夹中的便签数量 + *

+ * 查询指定文件夹中包含的便签数量 + *

+ * + * @param resolver ContentResolver对象 + * @param folderId 文件夹ID + * @return 便签数量 + */ + public static int getNoteCount(ContentResolver resolver, long folderId) { + Cursor cursor = resolver.query( + Notes.CONTENT_NOTE_URI, + new String[] { "COUNT(*)" }, + NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "=?", + new String[] { String.valueOf(Notes.TYPE_NOTE), String.valueOf(folderId) }, + null + ); + + int count = 0; + if (cursor != null) { + if (cursor.moveToFirst()) { + try { + count = cursor.getInt(0); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "get note count failed:" + e.toString()); + } finally { + cursor.close(); + } + } + } + return count; + } + + /** + * 获取未分类的便签数量 + *

+ * 查询直接在根文件夹中的便签数量,即未分类的便签 + *

+ * + * @param resolver ContentResolver对象 + * @return 未分类的便签数量 + */ + public static int getUncategorizedNoteCount(ContentResolver resolver) { + // 未分类的便签就是直接在根文件夹中的便签 + return getNoteCount(resolver, Notes.ID_ROOT_FOLDER); + } } diff --git a/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/main/java/net/micode/notes/ui/NotesListActivity.java index 29f4275..6ffe5f4 100644 --- a/src/main/java/net/micode/notes/ui/NotesListActivity.java +++ b/src/main/java/net/micode/notes/ui/NotesListActivity.java @@ -70,6 +70,12 @@ import android.widget.Toast; import android.widget.GridView; import android.widget.BaseAdapter; import android.view.ViewGroup; +import android.widget.ScrollView; +import androidx.drawerlayout.widget.DrawerLayout; +import android.view.Gravity; +import androidx.core.view.GravityCompat; +import java.util.List; +import java.util.ArrayList; import net.micode.notes.R; import net.micode.notes.data.Notes; @@ -115,10 +121,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt // 背景选项 private static final String[] BACKGROUND_OPTIONS = { - "高山流水", "风中树叶", "长河落日" + "高山流水", "风中树叶", "长河落日" }; private static final int[] BACKGROUND_RESOURCES = { - R.drawable.background_mountain, R.drawable.background_leaves, R.drawable.background_sunset + R.drawable.background_mountain, R.drawable.background_leaves, R.drawable.background_sunset }; private ListEditState mState; @@ -152,9 +158,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private NoteItemData mFocusNoteDataItem; - private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=? AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO; + private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=? AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER; - private static final String ROOT_FOLDER_SELECTION = "(" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.PARENT_ID + "=?) OR (" + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " + NoteColumns.NOTES_COUNT + ">0)"; + private static final String ROOT_FOLDER_SELECTION = NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER + " AND " + NoteColumns.PARENT_ID + "=?"; // 隐私空间相关常量 private static final int REQUEST_CODE_PRIVACY_SPACE = 104; @@ -179,11 +185,39 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private int mCurrentBackgroundResource = R.drawable.list_background; private String mCurrentBackgroundPath = ""; + // 侧边栏相关变量 + private Button mSidebarToggleButton; + private ListView mFolderListView; + private SidebarAdapter mFolderAdapter; + private ListView mUserFolderListView; + private SidebarAdapter mUserFolderAdapter; + private ImageView mAddFolderButton; + + // 标签选择相关 + private String mSelectedTag = ""; + + // 分类侧边栏相关 + private SidebarAdapter mCategoryAdapter = null; + private ListView mCategoryListView = null; + + // 标签侧边栏相关 + private SidebarAdapter mTagAdapter = null; + private ListView mTagListView = null; + + // 快速视图相关 + private SidebarAdapter mQuickViewAdapter = null; + private ListView mQuickViewListView = null; + + // 统计相关 + private TextView mTotalNotesTextView = null; + private TextView mPinnedNotesTextView = null; + private TextView mTodoNotesTextView = null; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.note_list); - + // 获取隐私空间ID Intent intent = getIntent(); if (intent != null) { @@ -192,8 +226,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt mCurrentPrivacySpaceId = ""; } } - + initResources(); + initSidebar(); initBackground(); /** @@ -370,13 +405,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); mPrivacyBackButton = (Button) findViewById(R.id.btn_privacy_back); mPrivacyBackButton.setOnClickListener(this); + mSidebarToggleButton = (Button) findViewById(R.id.btn_sidebar_toggle); + mSidebarToggleButton.setOnClickListener(this); mDispatch = false; mDispatchY = 0; mOriginY = 0; - mTitleBar = (TextView) findViewById(R.id.tv_title_bar); mMainContent = (LinearLayout) findViewById(R.id.main_content); // 获取根视图作为背景容器 - mBackgroundContainer = (RelativeLayout) findViewById(R.id.note_list_root); + mBackgroundContainer = (RelativeLayout) findViewById(R.id.main_content_container); if (mBackgroundContainer == null) { // 如果找不到,使用content view View contentView = getWindow().getDecorView().findViewById(android.R.id.content); @@ -404,7 +440,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } mState = ListEditState.NOTE_LIST; mModeCallBack = new ModeCallback(); - + // 检查是否处于隐私空间中 updatePrivacySpaceUI(); @@ -747,8 +783,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }; - // 当前选中的标签,用于筛选 - private String mSelectedTag = ""; + private void startAsyncNotesListQuery() { // 临时删除功能:输入"delete:1"删除ID为1的项目 @@ -766,45 +801,69 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt String baseSelection = ""; ArrayList argsList = new ArrayList<>(); - // 根据是否有搜索关键词构建不同的查询条件 - if (!TextUtils.isEmpty(mSearchQuery)) { - // 有搜索关键词的情况 - if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { - // 根文件夹:需要将搜索条件应用到两个部分 - baseSelection = "((" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=? AND (" + NoteColumns.TITLE + " LIKE ? OR " + NoteColumns.SNIPPET + " LIKE ? OR " + NoteColumns.TAGS + " LIKE ?))" - + " OR (" + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " + NoteColumns.NOTES_COUNT + ">0 AND (" + NoteColumns.TITLE + " LIKE ? OR " + NoteColumns.SNIPPET + " LIKE ? OR " + NoteColumns.TAGS + " LIKE ?)))"; - argsList.add(String.valueOf(mCurrentFolderId)); - argsList.add("%" + mSearchQuery + "%"); - argsList.add("%" + mSearchQuery + "%"); - argsList.add("%" + mSearchQuery + "%"); + // 处理未分类情况 + if (mCurrentFolderId == -1) { + // 未分类:查询所有不在文件夹中的便签 + if (!TextUtils.isEmpty(mSearchQuery)) { + // 有搜索关键词的情况 + baseSelection = NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER + " AND " + NoteColumns.PARENT_ID + "=" + Notes.ID_ROOT_FOLDER + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + " AND (" + NoteColumns.TITLE + " LIKE ? OR " + NoteColumns.SNIPPET + " LIKE ? OR " + NoteColumns.TAGS + " LIKE ?)"; argsList.add("%" + mSearchQuery + "%"); argsList.add("%" + mSearchQuery + "%"); argsList.add("%" + mSearchQuery + "%"); } else { - // 普通文件夹 - baseSelection = NORMAL_SELECTION + " AND (" + NoteColumns.TITLE + " LIKE ? OR " + NoteColumns.SNIPPET + " LIKE ? OR " + NoteColumns.TAGS + " LIKE ?)"; - argsList.add(String.valueOf(mCurrentFolderId)); - argsList.add("%" + mSearchQuery + "%"); - argsList.add("%" + mSearchQuery + "%"); - argsList.add("%" + mSearchQuery + "%"); + // 没有搜索关键词的情况 + baseSelection = NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER + " AND " + NoteColumns.PARENT_ID + "=" + Notes.ID_ROOT_FOLDER + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER; } } else { - // 没有搜索关键词的情况 - baseSelection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION : NORMAL_SELECTION; - argsList.add(String.valueOf(mCurrentFolderId)); + // 普通文件夹或根文件夹 + // 根据是否有搜索关键词构建不同的查询条件 + if (!TextUtils.isEmpty(mSearchQuery)) { + // 有搜索关键词的情况 + if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { + // 全部:查询所有文件夹中的便签,包括多级文件夹,但排除回收站 + baseSelection = NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + " AND (" + NoteColumns.TITLE + " LIKE ? OR " + NoteColumns.SNIPPET + " LIKE ? OR " + NoteColumns.TAGS + " LIKE ?)"; + argsList.add("%" + mSearchQuery + "%"); + argsList.add("%" + mSearchQuery + "%"); + argsList.add("%" + mSearchQuery + "%"); + } else { + // 普通文件夹:同时查询下一级文件夹和当前文件夹中的便签 + baseSelection = "(" + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE + " OR " + NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER + ") AND " + NoteColumns.PARENT_ID + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + " AND (" + NoteColumns.TITLE + " LIKE ? OR " + NoteColumns.SNIPPET + " LIKE ? OR " + NoteColumns.TAGS + " LIKE ?)"; + argsList.add(String.valueOf(mCurrentFolderId)); + argsList.add("%" + mSearchQuery + "%"); + argsList.add("%" + mSearchQuery + "%"); + argsList.add("%" + mSearchQuery + "%"); + } + } else { + // 没有搜索关键词的情况 + if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { + // 全部:查询所有文件夹中的便签,包括多级文件夹,但排除回收站 + baseSelection = NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER; + } else { + // 普通文件夹:同时查询下一级文件夹和当前文件夹中的便签 + baseSelection = "(" + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE + " OR " + NoteColumns.TYPE + "=" + Notes.TYPE_FOLDER + ") AND " + NoteColumns.PARENT_ID + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER; + argsList.add(String.valueOf(mCurrentFolderId)); + } + } } // 添加标签筛选条件 if (!TextUtils.isEmpty(mSelectedTag)) { - if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { + if (mCurrentFolderId == -1) { + // 未分类情况 + if (baseSelection.contains("AND")) { + baseSelection += " AND " + NoteColumns.TAGS + " LIKE ?"; + } else { + baseSelection += " AND " + NoteColumns.TAGS + " LIKE ?"; + } + argsList.add("%" + mSelectedTag + "%"); + } else if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { // 根文件夹需要特殊处理 String tagCondition = " AND " + NoteColumns.TAGS + " LIKE ?"; // 根据是否有搜索关键词构建不同的标签筛选条件 if (!TextUtils.isEmpty(mSearchQuery)) { // 有搜索关键词的情况 - baseSelection = "((" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=? AND (" + NoteColumns.TITLE + " LIKE ? OR " + NoteColumns.SNIPPET + " LIKE ? OR " + NoteColumns.TAGS + " LIKE ?)" + tagCondition + ")" - + " OR (" + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " + NoteColumns.NOTES_COUNT + ">0 AND (" + NoteColumns.TITLE + " LIKE ? OR " + NoteColumns.SNIPPET + " LIKE ? OR " + NoteColumns.TAGS + " LIKE ?)" + tagCondition + "))"; + baseSelection = NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER + " AND " + NoteColumns.PARENT_ID + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + " AND (" + NoteColumns.TITLE + " LIKE ? OR " + NoteColumns.SNIPPET + " LIKE ? OR " + NoteColumns.TAGS + " LIKE ?)" + tagCondition; // 重新构建参数列表 argsList.clear(); @@ -813,20 +872,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt argsList.add("%" + mSearchQuery + "%"); argsList.add("%" + mSearchQuery + "%"); argsList.add("%" + mSelectedTag + "%"); - argsList.add("%" + mSearchQuery + "%"); - argsList.add("%" + mSearchQuery + "%"); - argsList.add("%" + mSearchQuery + "%"); - argsList.add("%" + mSelectedTag + "%"); } else { // 没有搜索关键词的情况 - baseSelection = "((" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?" + tagCondition + ")" - + " OR (" + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " + NoteColumns.NOTES_COUNT + ">0" + tagCondition + "))"; + baseSelection = NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER + " AND " + NoteColumns.PARENT_ID + "=? AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + tagCondition; // 重新构建参数列表 argsList.clear(); argsList.add(String.valueOf(mCurrentFolderId)); argsList.add("%" + mSelectedTag + "%"); - argsList.add("%" + mSelectedTag + "%"); } } else { // 普通文件夹 @@ -843,19 +896,27 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt if (!TextUtils.isEmpty(mCurrentPrivacySpaceId)) { // 在隐私空间中,只显示该隐私空间的便签 String privacyCondition = NoteColumns.PRIVACY_SPACE_ID + "=?"; - if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { + if (mCurrentFolderId == -1) { + // 未分类情况 + baseSelection = "(" + baseSelection + ") AND " + privacyCondition; + argsList.add(mCurrentPrivacySpaceId); + } else if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { // 根文件夹需要特殊处理 if (!TextUtils.isEmpty(mSearchQuery) || !TextUtils.isEmpty(mSelectedTag)) { // 有搜索关键词或标签的情况 baseSelection = "(" + baseSelection + ") AND " + privacyCondition; } else { // 没有搜索关键词和标签的情况 - baseSelection = "(" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=? AND " + privacyCondition + ")"; + baseSelection = NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER + " AND " + NoteColumns.PARENT_ID + "=? AND " + privacyCondition; // 重新构建参数列表 argsList.clear(); argsList.add(String.valueOf(mCurrentFolderId)); argsList.add(mCurrentPrivacySpaceId); } + if (!TextUtils.isEmpty(mSearchQuery) || !TextUtils.isEmpty(mSelectedTag)) { + // 有搜索关键词或标签的情况,需要添加隐私空间ID参数 + argsList.add(mCurrentPrivacySpaceId); + } } else { // 普通文件夹 if (!TextUtils.isEmpty(mSearchQuery) || !TextUtils.isEmpty(mSelectedTag)) { @@ -863,40 +924,39 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt baseSelection = "(" + baseSelection + ") AND " + privacyCondition; } else { // 没有搜索关键词和标签的情况 - baseSelection = NoteColumns.PARENT_ID + "=? AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + privacyCondition; + baseSelection = NoteColumns.PARENT_ID + "=? AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_TODO + " AND " + NoteColumns.TYPE + "<>" + Notes.TYPE_FOLDER + " AND " + privacyCondition; // 重新构建参数列表 argsList.clear(); argsList.add(String.valueOf(mCurrentFolderId)); argsList.add(mCurrentPrivacySpaceId); } - } - if (!TextUtils.isEmpty(mSearchQuery) || !TextUtils.isEmpty(mSelectedTag)) { - // 有搜索关键词或标签的情况,需要添加隐私空间ID参数 - argsList.add(mCurrentPrivacySpaceId); + if (!TextUtils.isEmpty(mSearchQuery) || !TextUtils.isEmpty(mSelectedTag)) { + // 有搜索关键词或标签的情况,需要添加隐私空间ID参数 + argsList.add(mCurrentPrivacySpaceId); + } } } else { // 不在隐私空间中,只显示非隐私空间的便签 String privacyCondition = "(" + NoteColumns.PRIVACY_SPACE_ID + "='' OR " + NoteColumns.PRIVACY_SPACE_ID + " IS NULL)"; - if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { - // 根文件夹需要特殊处理 - baseSelection = "(" + baseSelection + ") AND " + privacyCondition; - } else { - // 普通文件夹 - if (baseSelection.contains("AND")) { - baseSelection += " AND " + privacyCondition; - } else { - baseSelection += " WHERE " + privacyCondition; - } - } + baseSelection = "(" + baseSelection + ") AND " + privacyCondition; } selection = baseSelection; selectionArgs = argsList.toArray(new String[argsList.size()]); + // 修改排序方式,确保文件夹显示在便签之前 + String sortOrder = ""; + if (mCurrentFolderId != Notes.ID_ROOT_FOLDER && mCurrentFolderId != -1) { + // 普通文件夹:先按类型排序(文件夹在前),再按修改日期排序 + sortOrder = NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"; + } else { + // 根文件夹或未分类:按原排序方式 + sortOrder = NoteColumns.IS_PINNED + " DESC," + NoteColumns.PIN_PRIORITY + " DESC," + + NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"; + } mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null, Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, selectionArgs, - NoteColumns.IS_PINNED + " DESC," + NoteColumns.PIN_PRIORITY + " DESC," + - NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); + sortOrder); } private final class BackgroundQueryHandler extends AsyncQueryHandler { @@ -953,12 +1013,24 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } private void batchDelete() { + if (mNotesListAdapter == null) { + Log.e(TAG, "mNotesListAdapter is null in batchDelete"); + Toast.makeText(this, "删除失败:适配器为空", Toast.LENGTH_SHORT).show(); + return; + } + + final HashSet selectedIds = mNotesListAdapter.getSelectedItemIds(); + if (selectedIds == null || selectedIds.isEmpty()) { + Log.e(TAG, "No items selected for deletion"); + Toast.makeText(this, "删除失败:未选择便签", Toast.LENGTH_SHORT).show(); + return; + } + new AsyncTask>() { protected HashSet doInBackground(Void... unused) { HashSet widgets = mNotesListAdapter.getSelectedWidget(); // Always move notes to trash folder for better user experience - if (!DataUtils.batchMoveToFolder(mContentResolver, mNotesListAdapter - .getSelectedItemIds(), Notes.ID_TRASH_FOLER)) { + if (!DataUtils.batchMoveToFolder(mContentResolver, selectedIds, Notes.ID_TRASH_FOLER)) { Log.e(TAG, "Move notes to trash folder error, should not happens"); } return widgets; @@ -974,7 +1046,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } } - mModeCallBack.finishActionMode(); + if (mModeCallBack != null) { + mModeCallBack.finishActionMode(); + } + // 重新加载侧边栏数据,更新数量显示 + loadSidebarData(); + // 重新加载便签列表,让删除的便签立即消失 + startAsyncNotesListQuery(); + // 显示删除成功的提示 + Toast.makeText(NotesListActivity.this, "已移至回收站", Toast.LENGTH_SHORT).show(); } }.execute(); } @@ -988,10 +1068,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt values.put(NoteColumns.PARENT_ID, Notes.ID_TRASH_FOLER); values.put(NoteColumns.LOCAL_MODIFIED, 1); values.put(NoteColumns.MODIFIED_DATE, System.currentTimeMillis()); - - int rows = mContentResolver.update(Notes.CONTENT_NOTE_URI, values, + + int rows = mContentResolver.update(Notes.CONTENT_NOTE_URI, values, NoteColumns.ID + "=?", new String[] { String.valueOf(itemId) }); - + if (rows > 0) { Log.d(TAG, "Successfully moved item " + itemId + " to trash"); Toast.makeText(this, "项目已移至回收站", Toast.LENGTH_SHORT).show(); @@ -999,7 +1079,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt Log.e(TAG, "Failed to move item " + itemId + " to trash"); Toast.makeText(this, "删除失败,请重试", Toast.LENGTH_SHORT).show(); } - + startAsyncNotesListQuery(); } @@ -1067,9 +1147,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt mCurrentPrivacySpaceId = ""; updatePrivacySpaceUI(); startAsyncNotesListQuery(); + } else if (v.getId() == R.id.btn_sidebar_toggle) { + // 切换侧边栏显示/隐藏 + toggleSidebar(); } } - + /** * 更新隐私空间相关的UI元素 */ @@ -1162,6 +1245,8 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt values.put(NoteColumns.TYPE, Notes.TYPE_FOLDER); values.put(NoteColumns.PARENT_ID, mCurrentFolderId); mContentResolver.insert(Notes.CONTENT_NOTE_URI, values); + // 重新加载侧边栏数据,确保新建的文件夹能显示出来 + loadSidebarData(); } dialog.dismiss(); } @@ -1208,11 +1293,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt new String[] { String.valueOf(mCurrentFolderId) }, null ); - + if (cursor != null && cursor.moveToFirst()) { long parentId = cursor.getLong(0); String folderName = cursor.getString(1); - + if (parentId == Notes.ID_ROOT_FOLDER) { // 返回到根文件夹 mCurrentFolderId = Notes.ID_ROOT_FOLDER; @@ -1255,7 +1340,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } } - + startAsyncNotesListQuery(); break; case CALL_RECORD_FOLDER: @@ -1471,6 +1556,504 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt from.startActivityIfNeeded(intent, -1); } + private View mAllItemView; + private TextView mAllTitleView; + private TextView mAllCountView; + private View mUncategorizedItemView; + private TextView mUncategorizedTitleView; + private TextView mUncategorizedCountView; + + private void initSidebar() { + mAllItemView = findViewById(R.id.all_item); + mAllTitleView = findViewById(R.id.all_title); + mAllCountView = findViewById(R.id.all_count); + mUncategorizedItemView = findViewById(R.id.uncategorized_item); + mUncategorizedTitleView = findViewById(R.id.uncategorized_title); + mUncategorizedCountView = findViewById(R.id.uncategorized_count); + mUserFolderListView = findViewById(R.id.user_folder_list); + mAddFolderButton = findViewById(R.id.add_folder_button); + + // 加载侧边栏数据 + loadSidebarData(); + + // 设置全部项点击事件 + mAllItemView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + // 更新选中状态 + updateTopItemSelection(true); + // 切换到全部 + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + startAsyncNotesListQuery(); + // 关闭侧边栏 + toggleSidebar(); + } + }); + + // 设置未分类项点击事件 + mUncategorizedItemView.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + // 更新选中状态 + updateTopItemSelection(false); + // 切换到未分类 + mCurrentFolderId = -1; + startAsyncNotesListQuery(); + // 关闭侧边栏 + toggleSidebar(); + } + }); + + // 设置用户文件夹列表点击事件 + mUserFolderListView.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mUserFolderAdapter.getItem(position); + if (item != null) { + // 更新选中状态 + updateUserFolderSelection(position); + // 切换到对应的文件夹 + mCurrentFolderId = item.getCategoryId(); + startAsyncNotesListQuery(); + // 关闭侧边栏 + toggleSidebar(); + } + } + }); + + // 设置用户文件夹列表长按事件,实现删除文件夹功能 + mUserFolderListView.setOnItemLongClickListener(new OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mUserFolderAdapter.getItem(position); + if (item != null) { + final long folderId = item.getCategoryId(); + if (folderId == Notes.ID_ROOT_FOLDER) { + // 根文件夹不能删除 + Toast.makeText(NotesListActivity.this, "根文件夹不能删除", Toast.LENGTH_SHORT).show(); + return true; + } + + // 显示确认删除对话框 + AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); + builder.setTitle("确认删除"); + builder.setMessage("确定要删除文件夹 \"" + item.getTitle() + "\" 吗?"); + builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // 删除文件夹 + deleteFolder(folderId); + // 重新加载侧边栏数据 + loadSidebarData(); + // 显示删除成功提示 + Toast.makeText(NotesListActivity.this, "文件夹已删除", Toast.LENGTH_SHORT).show(); + } + }); + builder.setNegativeButton("取消", null); + builder.show(); + return true; + } + return false; + } + }); + + // 设置添加文件夹按钮点击事件 + mAddFolderButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + showCreateOrModifyFolderDialog(true); + // 关闭侧边栏 + toggleSidebar(); + } + }); + } + + private void loadSidebarData() { + // 加载全部项数据 + int totalNotesCount = getTotalNoteCount(); + mAllCountView.setText(String.valueOf(totalNotesCount)); + if (totalNotesCount > 0) { + mAllCountView.setVisibility(View.VISIBLE); + } else { + mAllCountView.setVisibility(View.GONE); + } + + // 加载未分类项数据 + int uncategorizedCount = DataUtils.getUncategorizedNoteCount(mContentResolver); + mUncategorizedCountView.setText(String.valueOf(uncategorizedCount)); + if (uncategorizedCount > 0) { + mUncategorizedCountView.setVisibility(View.VISIBLE); + } else { + mUncategorizedCountView.setVisibility(View.GONE); + } + + // 加载用户文件夹(递归加载,显示层级结构) + List userFolderItems = new ArrayList<>(); + loadFoldersRecursive(Notes.ID_ROOT_FOLDER, userFolderItems, 0); + + // 创建并设置用户文件夹适配器 + mUserFolderAdapter = new SidebarAdapter(this, userFolderItems); + mUserFolderListView.setAdapter(mUserFolderAdapter); + + // 默认选中全部项 + updateTopItemSelection(true); + } + + private void updateFolderSelection(int position) { + // 取消所有顶部选项的选中状态 + if (mFolderAdapter != null) { + for (int i = 0; i < mFolderAdapter.getCount(); i++) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mFolderAdapter.getItem(i); + if (item != null) { + item.setSelected(false); + } + } + // 设置当前选项为选中状态 + SidebarAdapter.SidebarItem currentItem = (SidebarAdapter.SidebarItem) mFolderAdapter.getItem(position); + if (currentItem != null) { + currentItem.setSelected(true); + } + mFolderAdapter.notifyDataSetChanged(); + } + // 取消所有用户文件夹的选中状态 + if (mUserFolderAdapter != null) { + for (int i = 0; i < mUserFolderAdapter.getCount(); i++) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mUserFolderAdapter.getItem(i); + if (item != null) { + item.setSelected(false); + } + } + mUserFolderAdapter.notifyDataSetChanged(); + } + } + + private void updateTopItemSelection(boolean selectAll) { + // 重置所有顶部选项的状态 + mAllItemView.setBackgroundColor(getResources().getColor(R.color.surface, null)); + mAllTitleView.setTextColor(getResources().getColor(R.color.onSurface, null)); + mAllCountView.setTextColor(getResources().getColor(R.color.primary, null)); + mUncategorizedItemView.setBackgroundColor(getResources().getColor(R.color.surface, null)); + mUncategorizedTitleView.setTextColor(getResources().getColor(R.color.onSurface, null)); + mUncategorizedCountView.setTextColor(getResources().getColor(R.color.primary, null)); + + // 取消所有用户文件夹的选中状态 + if (mUserFolderAdapter != null) { + for (int i = 0; i < mUserFolderAdapter.getCount(); i++) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mUserFolderAdapter.getItem(i); + if (item != null) { + item.setSelected(false); + } + } + mUserFolderAdapter.notifyDataSetChanged(); + } + + // 设置选中状态 + if (selectAll) { + mAllItemView.setBackgroundColor(getResources().getColor(R.color.primary, null)); + mAllTitleView.setTextColor(getResources().getColor(R.color.onPrimary, null)); + mAllCountView.setTextColor(getResources().getColor(R.color.onPrimary, null)); + } else { + mUncategorizedItemView.setBackgroundColor(getResources().getColor(R.color.primary, null)); + mUncategorizedTitleView.setTextColor(getResources().getColor(R.color.onPrimary, null)); + mUncategorizedCountView.setTextColor(getResources().getColor(R.color.onPrimary, null)); + } + } + + private void updateUserFolderSelection(int position) { + // 重置所有顶部选项的状态 + mAllItemView.setBackgroundColor(getResources().getColor(R.color.surface, null)); + mAllTitleView.setTextColor(getResources().getColor(R.color.onSurface, null)); + mAllCountView.setTextColor(getResources().getColor(R.color.primary, null)); + mUncategorizedItemView.setBackgroundColor(getResources().getColor(R.color.surface, null)); + mUncategorizedTitleView.setTextColor(getResources().getColor(R.color.onSurface, null)); + mUncategorizedCountView.setTextColor(getResources().getColor(R.color.primary, null)); + + // 取消所有用户文件夹的选中状态 + if (mUserFolderAdapter != null) { + for (int i = 0; i < mUserFolderAdapter.getCount(); i++) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mUserFolderAdapter.getItem(i); + if (item != null) { + item.setSelected(false); + } + } + + // 设置当前文件夹为选中状态 + SidebarAdapter.SidebarItem currentItem = (SidebarAdapter.SidebarItem) mUserFolderAdapter.getItem(position); + if (currentItem != null) { + currentItem.setSelected(true); + } + mUserFolderAdapter.notifyDataSetChanged(); + } + } + + /** + * 更新侧边栏的选中状态,根据当前文件夹ID选择对应的侧边栏项 + */ + private void updateSidebarSelection() { + if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) { + // 当前在根文件夹,选中全部项 + updateTopItemSelection(true); + } else if (mCurrentFolderId == -1) { + // 当前在未分类,选中未分类项 + updateTopItemSelection(false); + } else { + // 当前在用户文件夹,找到并选中对应的文件夹项 + if (mUserFolderAdapter != null) { + for (int i = 0; i < mUserFolderAdapter.getCount(); i++) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mUserFolderAdapter.getItem(i); + if (item != null && item.getCategoryId() == mCurrentFolderId) { + updateUserFolderSelection(i); + break; + } + } + } + } + } + + /** + * 获取所有文件夹中的便签总数,包括多级文件夹 + */ + private int getTotalNoteCount() { + // 递归获取所有文件夹中的便签数量 + return getNoteCountRecursive(Notes.ID_ROOT_FOLDER); + } + + /** + * 递归获取文件夹及其子文件夹中的便签数量 + */ + private int getNoteCountRecursive(long folderId) { + int count = 0; + + // 获取当前文件夹中的便签数量(只统计普通便签,不统计待办事项) + Cursor noteCursor = mContentResolver.query( + Notes.CONTENT_NOTE_URI, + new String[] { "COUNT(*)" }, + NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "=?", + new String[] { String.valueOf(Notes.TYPE_NOTE), String.valueOf(folderId) }, + null + ); + + if (noteCursor != null) { + if (noteCursor.moveToFirst()) { + try { + count = noteCursor.getInt(0); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "get note count failed:" + e.toString()); + } finally { + noteCursor.close(); + } + } + } + + // 获取当前文件夹中的子文件夹 + Cursor folderCursor = mContentResolver.query( + Notes.CONTENT_NOTE_URI, + new String[] { NoteColumns.ID }, + NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "=?", + new String[] { String.valueOf(Notes.TYPE_FOLDER), String.valueOf(folderId) }, + null + ); + + if (folderCursor != null) { + while (folderCursor.moveToNext()) { + try { + long childFolderId = folderCursor.getLong(0); + // 递归获取子文件夹中的便签数量 + count += getNoteCountRecursive(childFolderId); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "get folder id failed:" + e.toString()); + } + } + folderCursor.close(); + } + + return count; + } + + /** + * 递归加载文件夹及其子文件夹,显示层级结构 + */ + private void loadFoldersRecursive(long parentFolderId, List folderItems, int level) { + // 获取当前文件夹下的子文件夹 + Cursor folderCursor = mContentResolver.query( + Notes.CONTENT_NOTE_URI, + new String[]{NoteColumns.ID, NoteColumns.SNIPPET, NoteColumns.NOTES_COUNT}, + NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "=?", + new String[]{String.valueOf(Notes.TYPE_FOLDER), String.valueOf(parentFolderId)}, + NoteColumns.MODIFIED_DATE + " DESC" + ); + + if (folderCursor != null) { + while (folderCursor.moveToNext()) { + try { + long folderId = folderCursor.getLong(0); + String folderName = folderCursor.getString(1); + int noteCount = folderCursor.getInt(2); + + // 根据层级添加缩进 + StringBuilder indentedName = new StringBuilder(); + for (int i = 0; i < level; i++) { + indentedName.append(" "); // 每级添加两个空格的缩进 + } + indentedName.append(folderName); + + // 添加文件夹项 + folderItems.add(new SidebarAdapter.SidebarItem(indentedName.toString(), noteCount, folderId)); + + // 递归加载子文件夹 + loadFoldersRecursive(folderId, folderItems, level + 1); + } catch (IndexOutOfBoundsException e) { + Log.e(TAG, "load folder failed:" + e.toString()); + } + } + folderCursor.close(); + } + } + + private void initCategoryData() { + // 模拟分类数据,实际应该从数据库获取 + List categories = new ArrayList<>(); + categories.add(new SidebarAdapter.SidebarItem("全部便签", 15, Notes.ID_ROOT_FOLDER)); + categories.add(new SidebarAdapter.SidebarItem("工作", 8, 1)); + categories.add(new SidebarAdapter.SidebarItem("生活", 5, 2)); + categories.add(new SidebarAdapter.SidebarItem("学习", 2, 3)); + + mCategoryAdapter = new SidebarAdapter(this, categories); + mCategoryListView.setAdapter(mCategoryAdapter); + + // 默认选中第一个分类 + if (!categories.isEmpty()) { + categories.get(0).setSelected(true); + mCategoryAdapter.notifyDataSetChanged(); + } + } + + private void initTagData() { + // 模拟标签数据,实际应该从数据库获取 + List tags = new ArrayList<>(); + tags.add(new SidebarAdapter.SidebarItem("重要", 5, "重要")); + tags.add(new SidebarAdapter.SidebarItem("紧急", 3, "紧急")); + tags.add(new SidebarAdapter.SidebarItem("想法", 4, "想法")); + tags.add(new SidebarAdapter.SidebarItem("计划", 2, "计划")); + + mTagAdapter = new SidebarAdapter(this, tags); + mTagListView.setAdapter(mTagAdapter); + } + + private void initQuickViewData() { + // 初始化快捷视图数据 + List quickViews = new ArrayList<>(); + quickViews.add(new SidebarAdapter.SidebarItem("全部便签", 15, SidebarAdapter.SidebarItem.QuickViewType.ALL)); + quickViews.add(new SidebarAdapter.SidebarItem("已置顶", 3, SidebarAdapter.SidebarItem.QuickViewType.PINNED)); + quickViews.add(new SidebarAdapter.SidebarItem("今天", 2, SidebarAdapter.SidebarItem.QuickViewType.TODAY)); + quickViews.add(new SidebarAdapter.SidebarItem("无标签", 6, SidebarAdapter.SidebarItem.QuickViewType.UNTAGGED)); + + mQuickViewAdapter = new SidebarAdapter(this, quickViews); + mQuickViewListView.setAdapter(mQuickViewAdapter); + + // 默认选中第一个快捷视图 + if (!quickViews.isEmpty()) { + quickViews.get(0).setSelected(true); + mQuickViewAdapter.notifyDataSetChanged(); + } + } + + private void initNoteStatistics() { + // 模拟统计数据,实际应该从数据库获取 + mTotalNotesTextView.setText("15"); + mPinnedNotesTextView.setText("3"); + mTodoNotesTextView.setText("2"); + } + + private void updateCategorySelection(int position) { + // 取消所有分类的选中状态 + if (mCategoryAdapter != null) { + for (int i = 0; i < mCategoryAdapter.getCount(); i++) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mCategoryAdapter.getItem(i); + if (item != null) { + item.setSelected(false); + } + } + // 设置当前分类为选中状态 + SidebarAdapter.SidebarItem currentItem = (SidebarAdapter.SidebarItem) mCategoryAdapter.getItem(position); + if (currentItem != null) { + currentItem.setSelected(true); + } + mCategoryAdapter.notifyDataSetChanged(); + } + } + + private void updateTagSelection(int position) { + // 取消所有标签的选中状态 + if (mTagAdapter != null) { + for (int i = 0; i < mTagAdapter.getCount(); i++) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mTagAdapter.getItem(i); + if (item != null) { + item.setSelected(false); + } + } + // 设置当前标签为选中状态 + SidebarAdapter.SidebarItem currentItem = (SidebarAdapter.SidebarItem) mTagAdapter.getItem(position); + if (currentItem != null) { + currentItem.setSelected(true); + } + mTagAdapter.notifyDataSetChanged(); + } + } + + private void updateQuickViewSelection(int position) { + // 取消所有快捷视图的选中状态 + if (mQuickViewAdapter != null) { + for (int i = 0; i < mQuickViewAdapter.getCount(); i++) { + SidebarAdapter.SidebarItem item = (SidebarAdapter.SidebarItem) mQuickViewAdapter.getItem(i); + if (item != null) { + item.setSelected(false); + } + } + // 设置当前快捷视图为选中状态 + SidebarAdapter.SidebarItem currentItem = (SidebarAdapter.SidebarItem) mQuickViewAdapter.getItem(position); + if (currentItem != null) { + currentItem.setSelected(true); + } + mQuickViewAdapter.notifyDataSetChanged(); + } + } + + private void applyQuickViewFilter(SidebarAdapter.SidebarItem.QuickViewType type) { + // 根据快捷视图类型应用不同的筛选条件 + switch (type) { + case ALL: + // 清除所有筛选条件 + mCurrentFolderId = Notes.ID_ROOT_FOLDER; + mSelectedTag = ""; + break; + case PINNED: + // 只显示已置顶的便签 + // 这里需要在startAsyncNotesListQuery中添加置顶筛选逻辑 + break; + case TODAY: + // 只显示今天创建或修改的便签 + // 这里需要在startAsyncNotesListQuery中添加日期筛选逻辑 + break; + case UNTAGGED: + // 只显示无标签的便签 + mSelectedTag = ""; + // 这里需要在startAsyncNotesListQuery中添加无标签筛选逻辑 + break; + } + } + + private void toggleSidebar() { + DrawerLayout drawerLayout = findViewById(R.id.drawer_layout); + if (drawerLayout != null) { + if (drawerLayout.isDrawerOpen(GravityCompat.START)) { + drawerLayout.closeDrawer(GravityCompat.START); + } else { + drawerLayout.openDrawer(GravityCompat.START); + } + } + } + private class OnListItemClickListener implements OnItemClickListener { public void onItemClick(AdapterView parent, View view, int position, long id) { @@ -1485,27 +2068,18 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return; } - switch (mState) { - case NOTE_LIST: - case SUB_FOLDER: - if (item.getType() == Notes.TYPE_FOLDER - || item.getType() == Notes.TYPE_SYSTEM) { - openFolder(item); - } else if (item.getType() == Notes.TYPE_NOTE) { - openNode(item); - } else { - Log.e(TAG, "Wrong note type in NOTE_LIST or SUB_FOLDER"); - } - break; - case CALL_RECORD_FOLDER: - if (item.getType() == Notes.TYPE_NOTE) { - openNode(item); - } else { - Log.e(TAG, "Wrong note type in CALL_RECORD_FOLDER"); - } - break; - default: - break; + // 处理便签点击 + if (item.getType() == Notes.TYPE_NOTE) { + openNode(item); + } + // 处理文件夹点击 + else if (item.getType() == Notes.TYPE_FOLDER) { + // 更新当前文件夹ID + mCurrentFolderId = item.getId(); + // 重新加载便签列表,显示该文件夹的内容 + startAsyncNotesListQuery(); + // 更新侧边栏的选中状态 + updateSidebarSelection(); } } } @@ -1736,14 +2310,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); mCurrentBackgroundType = sp.getString(PREFERENCE_BACKGROUND + "_type", BACKGROUND_TYPE_DEFAULT); mCurrentBackgroundPath = sp.getString(PREFERENCE_BACKGROUND + "_path", ""); - + if (BACKGROUND_TYPE_DEFAULT.equals(mCurrentBackgroundType)) { int backgroundIndex = sp.getInt(PREFERENCE_BACKGROUND + "_index", 0); if (backgroundIndex >= 0 && backgroundIndex < BACKGROUND_RESOURCES.length) { mCurrentBackgroundResource = BACKGROUND_RESOURCES[backgroundIndex]; } } - + // 更新背景 updateBackground(); } @@ -1755,7 +2329,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt if (mBackgroundContainer == null) { return; } - + try { if (BACKGROUND_TYPE_DEFAULT.equals(mCurrentBackgroundType)) { // 使用默认背景 @@ -1773,23 +2347,23 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt // 如果是内部存储路径 bitmap = android.graphics.BitmapFactory.decodeFile(mCurrentBackgroundPath); } - + if (bitmap != null) { // 计算屏幕尺寸 android.util.DisplayMetrics displayMetrics = new android.util.DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); int screenWidth = displayMetrics.widthPixels; int screenHeight = displayMetrics.heightPixels; - + // 缩放图片以适配屏幕 android.graphics.Bitmap scaledBitmap = android.graphics.Bitmap.createScaledBitmap( bitmap, screenWidth, screenHeight, true); - + android.graphics.drawable.BitmapDrawable drawable = new android.graphics.drawable.BitmapDrawable(getResources(), scaledBitmap); // 设置背景图片的缩放方式 drawable.setTileModeXY(android.graphics.Shader.TileMode.CLAMP, android.graphics.Shader.TileMode.CLAMP); mBackgroundContainer.setBackground(drawable); - + // 释放原始 bitmap if (bitmap != scaledBitmap) { bitmap.recycle(); @@ -1817,7 +2391,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt SharedPreferences.Editor editor = sp.edit(); editor.putString(PREFERENCE_BACKGROUND + "_type", mCurrentBackgroundType); editor.putString(PREFERENCE_BACKGROUND + "_path", mCurrentBackgroundPath); - + if (BACKGROUND_TYPE_DEFAULT.equals(mCurrentBackgroundType)) { // 找到当前背景资源的索引 int index = 0; @@ -1829,7 +2403,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } editor.putInt(PREFERENCE_BACKGROUND + "_index", index); } - + editor.apply(); } @@ -1839,12 +2413,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private void showBackgroundSelectorDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("选择背景"); - + // 创建背景选项数组,添加从相册选择的选项 String[] options = new String[BACKGROUND_OPTIONS.length + 1]; System.arraycopy(BACKGROUND_OPTIONS, 0, options, 0, BACKGROUND_OPTIONS.length); options[BACKGROUND_OPTIONS.length] = "从相册选择"; - + builder.setItems(options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { @@ -1865,7 +2439,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } }); - + builder.show(); } diff --git a/src/main/java/net/micode/notes/ui/SidebarAdapter.java b/src/main/java/net/micode/notes/ui/SidebarAdapter.java new file mode 100644 index 0000000..060a3e1 --- /dev/null +++ b/src/main/java/net/micode/notes/ui/SidebarAdapter.java @@ -0,0 +1,142 @@ +package net.micode.notes.ui; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +import net.micode.notes.R; + +import java.util.List; + +public class SidebarAdapter extends BaseAdapter { + private Context mContext; + private List mItems; + + public SidebarAdapter(Context context, List items) { + mContext = context; + mItems = items; + } + + @Override + public int getCount() { + return mItems != null ? mItems.size() : 0; + } + + @Override + public Object getItem(int position) { + return mItems != null ? mItems.get(position) : null; + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = LayoutInflater.from(mContext).inflate(R.layout.sidebar_item, parent, false); + } + + SidebarItem item = mItems.get(position); + TextView titleTextView = convertView.findViewById(R.id.item_title); + TextView countTextView = convertView.findViewById(R.id.item_count); + + titleTextView.setText(item.getTitle()); + if (item.getCount() > 0) { + countTextView.setVisibility(View.VISIBLE); + countTextView.setText(String.valueOf(item.getCount())); + } else { + countTextView.setVisibility(View.GONE); + } + + if (item.isSelected()) { + convertView.setBackgroundColor(mContext.getResources().getColor(R.color.primary, null)); + titleTextView.setTextColor(mContext.getResources().getColor(R.color.onPrimary, null)); + countTextView.setTextColor(mContext.getResources().getColor(R.color.onPrimary, null)); + } else { + convertView.setBackgroundColor(mContext.getResources().getColor(R.color.surface, null)); + titleTextView.setTextColor(mContext.getResources().getColor(R.color.onSurface, null)); + countTextView.setTextColor(mContext.getResources().getColor(R.color.primary, null)); + } + + return convertView; + } + + public static class SidebarItem { + private String mTitle; + private int mCount; + private boolean mSelected; + private String mTag; + private long mCategoryId; + private QuickViewType mQuickViewType; + + public SidebarItem(String title) { + mTitle = title; + mCount = 0; + mSelected = false; + } + + public SidebarItem(String title, int count) { + mTitle = title; + mCount = count; + mSelected = false; + } + + public SidebarItem(String title, int count, long categoryId) { + mTitle = title; + mCount = count; + mSelected = false; + mCategoryId = categoryId; + } + + public SidebarItem(String title, int count, String tag) { + mTitle = title; + mCount = count; + mSelected = false; + mTag = tag; + } + + public SidebarItem(String title, int count, QuickViewType type) { + mTitle = title; + mCount = count; + mSelected = false; + mQuickViewType = type; + } + + public String getTitle() { + return mTitle; + } + + public int getCount() { + return mCount; + } + + public boolean isSelected() { + return mSelected; + } + + public void setSelected(boolean selected) { + mSelected = selected; + } + + public String getTag() { + return mTag; + } + + public long getCategoryId() { + return mCategoryId; + } + + public QuickViewType getQuickViewType() { + return mQuickViewType; + } + + public enum QuickViewType { + ALL, PINNED, TODAY, UNTAGGED + } + } +} diff --git a/src/main/res/drawable/count_badge.xml b/src/main/res/drawable/count_badge.xml new file mode 100644 index 0000000..6e5f178 --- /dev/null +++ b/src/main/res/drawable/count_badge.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/src/main/res/drawable/ic_folder_add.xml b/src/main/res/drawable/ic_folder_add.xml new file mode 100644 index 0000000..13f65ef --- /dev/null +++ b/src/main/res/drawable/ic_folder_add.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/src/main/res/drawable/ic_format_color_bold.jpg b/src/main/res/drawable/ic_format_color_bold.jpg new file mode 100644 index 0000000000000000000000000000000000000000..29c3985673b89dc19f7db7e3d9cfacee12f35f32 GIT binary patch literal 1696 zcmb_ac~n$Y82{e98HPoSVNL1C$e!X9i-DSlhCyHy6;MOO0}cZWlcKXBipVGmnpm-@ z2xbJNpoN8~NhG@qW+j2_FpQAm(m4YJy=0izeNf`*^hYPV_uTh>_gjAV`+fJ49b`Y4 ztn}mi0fqr!Xaaek=E3LjB7;KK`tbu-OgU)w0*PcB9RT9DD`X-5KJ1NQo7hY>Fwryy zOJECxatSvmC=i9fUw;bEjPW*#9iU|q#dUk`@l*$;$!f1WvwO{tEmCLV{t+2Q$H;}q zqeUx5D3K{pvC#Ag&#}pP#SPoMK9n#&qX0%fSCg@nMslpMI<>{41o6l)NUuc zfrp;T%MFU;ZeF!=L>heMAZ508xgIyU|r@%uAM7Y6wAmQ5@Bn=Tg8MWfSkI+N0c(Gn@)EIMPp ztDY%0m?@B&*}Co5H}}aZEUz=La}Uv2M9G>BE$uzj4#SkRDP{joSn7XL_FUMEt}d8` zW9ag57I=eB=Uh~isp?oZt|ZDPwrSZ!+5|5-jD*z6lwPG?@|uDZ`s^YpPn~ zGp(OwgmKPhiyhr;+P82AgRsc!hqPwy<1VPM<;haQX`sM5r87gbFIjYIpybA0&Vz?H zRF|zjs5X7l^y#Bdyjsf?v})_SDICIS70cnuVEUM1qeE5n&eLZF`MQ=Tqq)~@G<+rD z#5}6yeomA$7L=1v_q~5a`;H3`jO#w&;3nDpXIE!}tc`)C6Of<9D_5=4%-0;RMx(Z!`NNkM!AI zsmi_CXG$avEIW0Yn^4ACqCOgV_zh0_Q2f{u&X`fgxiKTv&`F8+vq4=+PDG?8r@x@y zW?%Iy6&hyUj`V5+BD}xKGCN#pOjtGKN2XsYmb&&z_ekT%`0#-P;O{#bZ0u8#ki`W&=h9f2?-;9_U5KDlIGK|Jbn)RyDwmJqeY}fZVjez~Pt`HQP zDwX+T_86D4ZFPVRkR66DlG>ev=d@3ir$7|6yPniu2GX)+)<84>V;FNM=Doh}f_MVD z(QT7Axch;`OO!dU@HL0rI?D3zkeR_}5M{fE@LqAdQ2l46llxKy&z5%BPUwdY2C)5r zYYT2xaP@fDBP8XU_3D{_`j207*fxao?ZCbO000SaNLh0L02Uo#4->BD|-HH;zzsx0RICZF>1|b)3U7FISz$F zgb+>BG)?0K2#j-(&*vXi%jL3Znmhp33jFT1T8$9mJD%qa27_+5+w1j;#bT*c`V+tx zA%s$TeJvCU`~BXw?S8+{19)YVv)L>Ftk-Lv@GF4vcnkpXc$_C3{E6oC`Ssb~1KYL% zpi-&42hizs?oC;ilgT6x;KhUHd7fby)9ExgijPGprIZeb!&~!oI!z`MUDqk4)oS&8 zJ~KKX;?pY-MNw7NR;vX7tJP{Yn+4>b1^7y(Qn6SJ05+S=M*xoFY`0qgNF);P2OJIu z(=?CAV>B8~r_<~(YfJ?}K*V;t9S(=DCL%7EOUH2lpwVbZQox|I%DG%_G#V`yi~EwI zDD`@s=PqJh*RJbYmbKgMZcSO1GntI4s*y+}uzLXDE&Bd{@(=I>d;#DBGAP+wu?}rN P00000NkvXXu0mjf`vpUd diff --git a/src/main/res/drawable/ic_format_color_fill.jpg b/src/main/res/drawable/ic_format_color_fill.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4913d74ad280124cc4bc2165713d104e32c46595 GIT binary patch literal 2337 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 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable/ic_format_color_text.png b/src/main/res/drawable/ic_format_color_text.png deleted file mode 100644 index 645e83f06981953b5faf4b9fac05ea7e2f8fbea3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 726 zcmV;{0xA88P)%`0#-P;O{#bZ0u8#ki`W&=h9f2?-;9_U5KDlIGK|Jbn)RyDwmJqeY}fZVjez~Pt`HQP zDwX+T_86D4ZFPVRkR66DlG>ev=d@3ir$7|6yPniu2GX)+)<84>V;FNM=Doh}f_MVD z(QT7Axch;`OO!dU@HL0rI?D3zkeR_}5M{fE@LqAdQ2l46llxKy&z5%BPUwdY2C)5r zYYT2xaP@fDBP8XU_3D{_`j207*fxao?ZCbO000SaNLh0L02U|IF4zW%I2nNI*ya; zTmZg@`pwRDE~v586MHLi5kK{__mHj57s_g`|96hx;J*+40?~|}y>6b4Gynhq07*qo IM6N<$g0jy|+yDRo diff --git a/src/main/res/drawable/ic_format_italic.jpg b/src/main/res/drawable/ic_format_italic.jpg new file mode 100644 index 0000000000000000000000000000000000000000..12c85d7618904e3fe7bded1b8f1d27ee3d4a9f41 GIT binary patch literal 1717 zcmb_aX;f236uvJnAuKK=5UiplvI#1!Y@!^|0)hoMh+D;$G=wcK7?LQ&(~5u<(N;tR zE8PwVwWUQ%6*NErYY>-ON)Zsy5Tq`}g+v4%kmPk0P+saD z6OD;r16+YnD)tWxTY*yGuRn#yZLpPM2WWPqxUNpiO>;`IT)E)5RZCMZCv80MACY-< zj8upsIy7U1Vu=i0HX31vB$=4P`w_O5pi3eADTU+4@OKoB8pBFs&RSj|%DIU!R~Roq z92kM{+^84)aWCLM&qXO0T|20`mGSUGMxLqulh~na9Tz^!h7;Z>{ z@U^*Ik9qDs094J#PVEmj))KS%Y226I1>jdpl4RAmFSHh*4DB>mjQd;`0I)0oE-S|>S zKwSda34y3pUd||zmt#P?$vR+}f+KKo%pPbg3}<1a670}JGsd{bN{H4poX#*|nwptg zpoDTupkX*pqvH$)9d$bPK8gdK#bD2L_cyT$7clJ;tvyn+3rrmX$}VttO&UkfC`p=` zxy_VUrcQHmp5@{?+sk{t&w_=%flGsem%SMhx@PUV^&3#(h0!swaq*(fQrV83Ny+kE z>3cuem$5(dz>%Dzxp~JvKAvBAqNw=GlV5#Z^8J~!0%*WG&&upGbvpdEr}A& zqBCZ?o3Q=EnSw+sdyiC8>wxTnvI}Moo;(dFO44L*j>-t1|sgm38Z*Zohp+_>Jh?yvX)dHe2Mpp!G0gB}X@`!}K4<5cjpCgSlD3`m;;a zMV7l8?M%wIO;!)>i>=UC)-0+ixYKuVM7H{rZdFU^00~5h?paf{!^EMCYFEzQ@W-F5 z^KD-F`pBZhER`LN2=1(loTTYWck{005Jx&M`UZWTWm4O7n%!IDp*?hZ#?b($TJ5X@ z<<}0D^7$=K-0wwh-u02PZ3FMfQ-$*$-^$?)gH6Q49ix7R#>ES@KW9XDG#)x#`gqY) zO~b{*dxj#NiDNy>FTdxb{%n%UPbKiFd~zZ_XZdugZSv9_uN706y(PLw+9Vx2#b9>5 zr_UxitKn4-efDm4az_2)Ij!Y(mPC3)O|!SByyRg-`8Cz%h}_O)C63#q@*Q(?mfvld z{%!@^8$Ud`FeRFV)SX>tG9KwQUEMBKhSoMOx2XemwnS!ou|msNE@9ukh1gZD)#tO> zTQUdwIK8_{M}DXi6;|Y_ZdAEd=8w#-o};#VbVXw^xJh%VSl!s(*UjH+up;;yTMku~ zJWyGk$!l#3Yq|dIeE#-I(f#xJqWa?Md9L!%qQpH16kA72!8$z1I8(^>-M816Q5{`W T@J>JdQb}H|{ZU>LM?L%pih4?C literal 0 HcmV?d00001 diff --git a/src/main/res/drawable/ic_format_italic.png b/src/main/res/drawable/ic_format_italic.png deleted file mode 100644 index bdb9a04b36a1f9feac4e6b4c66fd2d7a216672c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 614 zcmV-s0-61ZP)%`0#-P;O{#bZ0u8#ki`W&=h9f2?-;9_U5KDlIGK|Jbn)RyDwmJqeY}fZVjez~Pt`HQP zDwX+T_86D4ZFPVRkR66DlG>ev=d@3ir$7|6yPniu2GX)+)<84>V;FNM=Doh}f_MVD z(QT7Axch;`OO!dU@HL0rI?D3zkeR_}5M{fE@LqAdQ2l46llxKy&z5%BPUwdY2C)5r zYYT2xaP@fDBP8XU_3D{_`j207*fxao?ZCbO000SaNLh0L02U3dz4zfs;Xfa9z2i#o$@?imc_R1gXb|Ngb;*KQ525j$Vzox zcU|W=&hZMS1R)dzK@>%@Qs4JgRXL7BQ50Dzj$@W(RaHIJIxQ{Bl4Y4?Su{Q=wOL~{|1=-KYGNY~T5&!@I07*qoM6N<$f_z~V AC;$Ke diff --git a/src/main/res/drawable/ic_format_underlined.jpg b/src/main/res/drawable/ic_format_underlined.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6c6d44ac1641eb9e5dc267cf09cddbcc6162d5a3 GIT binary patch literal 1779 zcmb_cYfw{16h1dMA%G|Z6co`!<<+X7AVM86LJ%6Tf#Q zR(w@(#tKr@)>5n}v0k>iB05Rz7Z$c2rNCcr1D>*>Rs%ag^HKxXP5Z+NC%M&oKF4fYn)+ucrt5-Hm3HiQ=?OT`A9gYZlV+7!aa4OlpdzcXOLB(62)M22%vPCLS^ z=r{s#V0wg?2ww9GU&DW{i&9`(fGA14gOIVpJPpJD*Q7BiNCyDtBe6^(62?hceyB<@ zEN)`7+Y*+?vgO_YhMG^VI=InTOU(ACDPLw6fUlAy$sebD!AgK~G}F9l%IE3>z?cSb zy-G|-2qPbko|M>FfPqqg>01D78qu7nq*zZ6V;r;a2cSJ5$w6lT`ayv4&q;E$h$P30 z0q~yzt|XG3z(H5#&CEdZW(;UHc?B4z;0O*lwh$-`3};|uEilnR(|-{L5=*g*Ry( zJp~elnYpdq>^b&M&MvNRy}iO~rMJ&Jt2hDc0)yV=21i8lHf=_QkKPs&D~uCuPm=EX zI5|c3N#^c7S=l*zbMp@#I(+2l7sm>Uicgh%ReJi&+4J9DsJM8kvg(Jc*J|tPRo8Fa zyxV-QrM0bH-O=6i=<$q~%g#rGmWRuGNri+1eQK(d$N;l}j zD9Hxl3@UBGauaL6jdWtC%|ee1)0zGUPL|i0E%FT4&JswP%xxW4bUWz`(u~UfoiN3J zQua#Nl&%i2z%g`qI0M))F_K;&4JP--{0GxeQ4 z?pK-nI!gDi=9Q%=c}?v26CH&$BZ((_<^}ggUM|t~w>-@%~M^JBrK1!!n2XiRqVGQoWLUa(;W!HA8=t)0XJcT-@R= zeHOLhP>@LGqWP?b+MrOqvurl|Jo6gG*J72L`R$ptcI+5s7Smz1d^BJzX#Ao)j!&u6 z3P03szLw|yu=FZ3<91o!0~Z}rk#5_bl99^$TBEe~%Cl+Ej_P~s(^(bGZp^^OUGpMB zwGBs0N_H3IJ$cfiQj@@qgfC~9tV)xW?Wwkw*LadZurtzEH?46=bsaCLW~R8Ss_kWu z8&g9{YR=9bcMB<$B?$BHeb8?cm7V`UL@d!>=Q$=6hFGU-9KhEVigJw|C)MfqBg_on W!!4g%o#xMm#cmIqP)%`0#-P;O{#bZ0u8#ki`W&=h9f2?-;9_U5KDlIGK|Jbn)RyDwmJqeY}fZVjez~Pt`HQP zDwX+T_86D4ZFPVRkR66DlG>ev=d@3ir$7|6yPniu2GX)+)<84>V;FNM=Doh}f_MVD z(QT7Axch;`OO!dU@HL0rI?D3zkeR_}5M{fE@LqAdQ2l46llxKy&z5%BPUwdY2C)5r zYYT2xaP@fDBP8XU_3D{_`j207*fxao?ZCbO000SaNLh0L02Uv?^h)7F2)#eTHem1pH-)na?Win=bTb{Twj)DT~}MXuIsWa$Ms*y zOaFWNwrvM0CmljK41=xh`yN7gTo1#r>pG>>eWjGTUaw&o?&`o;GL9o5B+D|b_1C%9 zI!#kT$TUs1-CL}>F{Z9-j4@+O2qC4EQVJm$V;JMQu6Jo;%;oWYZ`-!2s(GGo6W{mq zJa>8)0Csc$fY!Qcn$I5&f*^__&+}YpC;caRzaMeV%d&LbFNz|L<8SB)p(IHhb%fA^ j_S~0w)+_eX|EvB1=A890AL+&`00000NkvXXu0mjf`{)f# diff --git a/src/main/res/layout/note_list.xml b/src/main/res/layout/note_list.xml index 636abff..1ad1008 100644 --- a/src/main/res/layout/note_list.xml +++ b/src/main/res/layout/note_list.xml @@ -15,175 +15,221 @@ limitations under the License. --> - - + + android:layout_height="match_parent"> - + + + +