From a5a619b01c3380050fcee554234ef60de37bc4f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B6=E4=BF=8A=E5=AE=87?= <2643473564@qq.com> Date: Sun, 18 Jan 2026 12:02:41 +0800 Subject: [PATCH] =?UTF-8?q?UI=E9=81=AE=E6=8C=A1=E9=97=AE=E9=A2=98=E7=9A=84?= =?UTF-8?q?=E8=A1=A5=E5=85=85=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/net/micode/notes/data/Notes.java | 15 +- .../notes/data/NotesDatabaseHelper.java | 22 ++- .../net/micode/notes/ui/NoteItemData.java | 28 +++ .../micode/notes/ui/NotesListActivity.java | 168 ++++++++++++++++-- src/main/res/layout/note_edit.xml | 4 +- src/main/res/menu/note_list_options.xml | 5 + src/main/res/values-zh-rCN/strings.xml | 2 + src/main/res/values/strings.xml | 2 + 8 files changed, 227 insertions(+), 19 deletions(-) diff --git a/src/main/java/net/micode/notes/data/Notes.java b/src/main/java/net/micode/notes/data/Notes.java index 5d83908..4b82197 100644 --- a/src/main/java/net/micode/notes/data/Notes.java +++ b/src/main/java/net/micode/notes/data/Notes.java @@ -211,22 +211,29 @@ public class Notes { public static final String LOCAL_MODIFIED = "local_modified"; /** - * 移动到临时文件夹之前的原始父ID - *
类型: INTEGER
+ * 原始父ID + *类型: INTEGER (long)
*/ public static final String ORIGIN_PARENT_ID = "origin_parent_id"; /** - * GTask ID + * GTASK ID *类型: TEXT
*/ public static final String GTASK_ID = "gtask_id"; /** * 版本号 - *类型: INTEGER (long)
+ *类型: INTEGER
*/ public static final String VERSION = "version"; + + /** + * 置顶状态 + *类型: INTEGER
+ *0表示未置顶,1表示置顶
+ */ + public static final String PINNED = "pinned"; } public interface DataColumns { diff --git a/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java b/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java index f6b9c37..5eccfec 100644 --- a/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java +++ b/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java @@ -35,7 +35,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { // 数据库文件名 private static final String DB_NAME = "note.db"; // 数据库版本号,用于升级控制 - private static final int DB_VERSION = 4; + private static final int DB_VERSION = 5; /** * 数据库表名常量定义 @@ -56,7 +56,7 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { * 笔记表创建SQL语句 * 包含笔记/文件夹的基本属性:ID、父文件夹ID、提醒时间、背景色、创建/修改时间等 */ - private static final String CREATE_NOTE_TABLE_SQL = + private static final String CREATE_NOTE_TABLE_SQL = "CREATE TABLE " + TABLE.NOTE + "(" + NoteColumns.ID + " INTEGER PRIMARY KEY," + NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + @@ -74,7 +74,8 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," + NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," + - NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" + + NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.PINNED + " INTEGER NOT NULL DEFAULT 0" + ")"; /** @@ -378,6 +379,12 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { oldVersion++; } + // 版本4升级到版本5 + if (oldVersion == 4) { + upgradeToV5(db); + oldVersion++; + } + // 如果需要,重新创建触发器 if (reCreateTriggers) { reCreateNoteTableTriggers(db); @@ -429,4 +436,13 @@ public class NotesDatabaseHelper extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0"); } + + /** + * 升级到版本5:添加置顶字段,用于便签置顶功能 + * @param db 数据库实例 + */ + private void upgradeToV5(SQLiteDatabase db) { + db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.PINNED + + " INTEGER NOT NULL DEFAULT 0"); + } } \ No newline at end of file diff --git a/src/main/java/net/micode/notes/ui/NoteItemData.java b/src/main/java/net/micode/notes/ui/NoteItemData.java index 2ffa01d..44825ee 100644 --- a/src/main/java/net/micode/notes/ui/NoteItemData.java +++ b/src/main/java/net/micode/notes/ui/NoteItemData.java @@ -53,6 +53,7 @@ public class NoteItemData { NoteColumns.TYPE, NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, + NoteColumns.PINNED, }; /** @@ -114,12 +115,22 @@ public class NoteItemData { * 查询结果中小组件类型列的索引 */ private static final int WIDGET_TYPE_COLUMN = 11; + + /** + * 查询结果中置顶状态列的索引 + */ + private static final int PINNED_COLUMN = 12; /** * 笔记ID */ private long mId; + /** + * 置顶状态 + */ + private boolean mPinned; + /** * 提醒日期 */ @@ -230,6 +241,7 @@ public class NoteItemData { mType = cursor.getInt(TYPE_COLUMN); mWidgetId = cursor.getInt(WIDGET_ID_COLUMN); mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN); + mPinned = (cursor.getInt(PINNED_COLUMN) > 0) ? true : false; mPhoneNumber = ""; if (mParentId == Notes.ID_CALL_RECORD_FOLDER) { @@ -447,6 +459,22 @@ public class NoteItemData { public boolean isCallRecord() { return (mParentId == Notes.ID_CALL_RECORD_FOLDER && !TextUtils.isEmpty(mPhoneNumber)); } + + /** + * 获取置顶状态 + * @return 置顶状态,true表示已置顶,false表示未置顶 + */ + public boolean isPinned() { + return mPinned; + } + + /** + * 设置置顶状态 + * @param pinned 置顶状态,true表示置顶,false表示取消置顶 + */ + public void setPinned(boolean pinned) { + mPinned = pinned; + } /** * 获取笔记类型(静态方法) diff --git a/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/main/java/net/micode/notes/ui/NotesListActivity.java index 7cbe6ee..66ae5b7 100644 --- a/src/main/java/net/micode/notes/ui/NotesListActivity.java +++ b/src/main/java/net/micode/notes/ui/NotesListActivity.java @@ -148,6 +148,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt /** 模式回调 */ private ModeCallback mModeCallBack; + + /** 是否分发触摸事件 */ + private boolean mDispatch; + + /** 原始Y坐标 */ + private int mOriginY; + + /** 分发Y坐标 */ + private int mDispatchY; /** 日志标签 */ private static final String TAG = "NotesListActivity"; @@ -298,12 +307,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt mNotesListView.setAdapter(mNotesListAdapter); mAddNewNote = (Button) findViewById(R.id.btn_new_note); mAddNewNote.setOnClickListener(this); - // 移除复杂的OnTouchListener,简化触摸事件处理 - // mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); - // 移除不再需要的触摸事件相关变量 - // mDispatch = false; - // mDispatchY = 0; - // mOriginY = 0; + mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); + mDispatch = false; + mDispatchY = 0; + mOriginY = 0; mTitleBar = (TextView) findViewById(R.id.tv_title_bar); mState = ListEditState.NOTE_LIST; mModeCallBack = new ModeCallback(); @@ -354,6 +361,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt mMoveMenu.setVisible(true); mMoveMenu.setOnMenuItemClickListener(this); } + // 添加置顶菜单初始化 + MenuItem pinMenu = menu.findItem(R.id.pin); + if (pinMenu != null) { + pinMenu.setOnMenuItemClickListener(this); + } mActionMode = mode; mNotesListAdapter.setChoiceMode(true); mNotesListView.setLongClickable(false); @@ -513,6 +525,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt case R.id.move: startQueryDestinationFolders(); break; + case R.id.pin: + togglePinnedStatus(); + break; default: return false; } @@ -520,10 +535,93 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } - // 删除不再使用的NewNoteOnTouchListener内部类 - // private class NewNoteOnTouchListener implements OnTouchListener { - // // ... 内部类内容 ... - // }; + /** + * 新建笔记按钮触摸监听器 + *+ * 该类实现了OnTouchListener接口,用于处理新建笔记按钮的触摸事件, + * 特别是处理按钮透明部分的触摸事件,将其分发给下方的列表视图 + *
+ */ + private class NewNoteOnTouchListener implements OnTouchListener { + + /** + * 处理触摸事件 + *+ * 该方法完成以下工作: + * 1. 处理ACTION_DOWN事件: + * - 获取屏幕高度和新建笔记按钮高度 + * - 计算触摸事件的Y坐标 + * - 如果当前状态是SUB_FOLDER,减去标题栏高度 + * - 检查触摸点是否在按钮的透明部分(根据公式y=-0.12x+94判断) + * - 如果是,将触摸事件分发给下方的列表视图 + * 2. 处理ACTION_MOVE事件: + * - 如果已经开始分发事件,更新事件坐标并继续分发给列表视图 + * 3. 处理其他事件: + * - 如果已经开始分发事件,结束分发并将事件分发给列表视图 + *
+ * @param v 被触摸的视图 + * @param event 触摸事件 + * @return 是否消费了该事件,返回true表示已消费 + */ + public boolean onTouch(View v, MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: { + Display display = getWindowManager().getDefaultDisplay(); + int screenHeight = display.getHeight(); + int newNoteViewHeight = mAddNewNote.getHeight(); + int start = screenHeight - newNoteViewHeight; + int eventY = start + (int) event.getY(); + /** + * Minus TitleBar's height + */ + if (mState == ListEditState.SUB_FOLDER) { + eventY -= mTitleBar.getHeight(); + start -= mTitleBar.getHeight(); + } + /** + * HACKME:When click the transparent part of "New Note" button, dispatch + * the event to the list view behind this button. The transparent part of + * "New Note" button could be expressed by formula y=-0.12x+94(Unit:pixel) + * and the line top of the button. The coordinate based on left of the "New + * Note" button. The 94 represents maximum height of the transparent part. + * Notice that, if the background of the button changes, the formula should + * also change. This is very bad, just for the UI designer's strong requirement. + */ + if (event.getY() < (event.getX() * (-0.12) + 94)) { + View view = mNotesListView.getChildAt(mNotesListView.getChildCount() - 1 + - mNotesListView.getFooterViewsCount()); + if (view != null && view.getBottom() > start + && (view.getTop() < (start + 94))) { + mOriginY = (int) event.getY(); + mDispatchY = eventY; + event.setLocation(event.getX(), mDispatchY); + mDispatch = true; + return mNotesListView.dispatchTouchEvent(event); + } + } + break; + } + case MotionEvent.ACTION_MOVE: { + if (mDispatch) { + mDispatchY += (int) event.getY() - mOriginY; + event.setLocation(event.getX(), mDispatchY); + return mNotesListView.dispatchTouchEvent(event); + } + break; + } + default: { + if (mDispatch) { + event.setLocation(event.getX(), mDispatchY); + mDispatch = false; + return mNotesListView.dispatchTouchEvent(event); + } + break; + } + } + return false; + } + + }; /** * 启动异步笔记列表查询 @@ -537,7 +635,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null, Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] { String.valueOf(mCurrentFolderId) - }, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); + }, NoteColumns.PINNED + " DESC," + NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); } /** @@ -670,6 +768,54 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }.execute(); } + /** + * 切换选中便签的置顶状态 + */ + private void togglePinnedStatus() { + final HashSet
diff --git a/src/main/res/layout/note_edit.xml b/src/main/res/layout/note_edit.xml
index 10b2aa7..e0cf16b 100644
--- a/src/main/res/layout/note_edit.xml
+++ b/src/main/res/layout/note_edit.xml
@@ -19,6 +19,7 @@
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/list_background"
+ android:fitsSystemWindows="true"
xmlns:android="http://schemas.android.com/apk/res/android">