diff --git a/src/Notes-master/Notes-master.rar b/src/Notes-master/Notes-master.rar
new file mode 100644
index 0000000..c3186b6
Binary files /dev/null and b/src/Notes-master/Notes-master.rar differ
diff --git a/src/Notes-master/mainfests/AndroidManifest.xml b/src/Notes-master/mainfests/AndroidManifest.xml
new file mode 100644
index 0000000..9fb914f
--- /dev/null
+++ b/src/Notes-master/mainfests/AndroidManifest.xml
@@ -0,0 +1,160 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Notes-master/res/drawable-hdpi/new_note_normal.png b/src/Notes-master/res/drawable-hdpi/new_note_normal.png
index e24e0d1..ee9fb2d 100644
Binary files a/src/Notes-master/res/drawable-hdpi/new_note_normal.png and b/src/Notes-master/res/drawable-hdpi/new_note_normal.png differ
diff --git a/src/Notes-master/res/drawable-hdpi/new_note_pressed.png b/src/Notes-master/res/drawable-hdpi/new_note_pressed.png
index c748936..c7affa1 100644
Binary files a/src/Notes-master/res/drawable-hdpi/new_note_pressed.png and b/src/Notes-master/res/drawable-hdpi/new_note_pressed.png differ
diff --git a/src/Notes-master/res/drawable/ic_launcher_background.xml b/src/Notes-master/res/drawable/ic_launcher_background.xml
index 07d5da9..ca3826a 100644
--- a/src/Notes-master/res/drawable/ic_launcher_background.xml
+++ b/src/Notes-master/res/drawable/ic_launcher_background.xml
@@ -1,170 +1,74 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Notes-master/res/drawable/new_note_pressed_background.xml b/src/Notes-master/res/drawable/new_note_pressed_background.xml
new file mode 100644
index 0000000..ca3826a
--- /dev/null
+++ b/src/Notes-master/res/drawable/new_note_pressed_background.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Notes-master/res/layout/add_account_text.xml b/src/Notes-master/res/layout/add_account_text.xml
index c799178..7ce4ef8 100644
--- a/src/Notes-master/res/layout/add_account_text.xml
+++ b/src/Notes-master/res/layout/add_account_text.xml
@@ -15,18 +15,17 @@
limitations under the License.
-->
-
+ android:text="@string/preferences_add_account"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
\ No newline at end of file
diff --git a/src/Notes-master/res/layout/note_edit.xml b/src/Notes-master/res/layout/note_edit.xml
index 10b2aa7..efc2bdc 100644
--- a/src/Notes-master/res/layout/note_edit.xml
+++ b/src/Notes-master/res/layout/note_edit.xml
@@ -77,11 +77,11 @@
+ android:scrollbars="none">
+ android:textAppearance="@style/TextAppearancePrimaryItem" />
diff --git a/src/Notes-master/res/layout/note_item.xml b/src/Notes-master/res/layout/note_item.xml
index d541f6a..8e9ca44 100644
--- a/src/Notes-master/res/layout/note_item.xml
+++ b/src/Notes-master/res/layout/note_item.xml
@@ -27,6 +27,15 @@
android:layout_gravity="center_vertical"
android:gravity="center_vertical">
+
+
+
-
+
+ android:layout_weight="1">
+
+
+
+
+
+
+
-
+
diff --git a/src/Notes-master/res/layout/note_list.xml b/src/Notes-master/res/layout/note_list.xml
index 6b25d38..64aa1e0 100644
--- a/src/Notes-master/res/layout/note_list.xml
+++ b/src/Notes-master/res/layout/note_list.xml
@@ -36,6 +36,40 @@
android:singleLine="true"
android:textColor="#FFEAD1AE"
android:textSize="@dimen/text_font_size_medium" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/Notes-master/res/menu/note_list.xml b/src/Notes-master/res/menu/note_list.xml
index 42ea736..e21deab 100644
--- a/src/Notes-master/res/menu/note_list.xml
+++ b/src/Notes-master/res/menu/note_list.xml
@@ -32,8 +32,4 @@
-
-
diff --git a/src/Notes-master/res/mipmap-anydpi-v26/ic_launcher.xml b/src/Notes-master/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..c4a603d
--- /dev/null
+++ b/src/Notes-master/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Notes-master/res/mipmap-anydpi-v26/ic_launcher_round.xml b/src/Notes-master/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..c4a603d
--- /dev/null
+++ b/src/Notes-master/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Notes-master/res/mipmap-anydpi-v26/new_note_pressed.xml b/src/Notes-master/res/mipmap-anydpi-v26/new_note_pressed.xml
new file mode 100644
index 0000000..b7d09c6
--- /dev/null
+++ b/src/Notes-master/res/mipmap-anydpi-v26/new_note_pressed.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Notes-master/res/mipmap-anydpi-v26/new_note_pressed_round.xml b/src/Notes-master/res/mipmap-anydpi-v26/new_note_pressed_round.xml
new file mode 100644
index 0000000..b7d09c6
--- /dev/null
+++ b/src/Notes-master/res/mipmap-anydpi-v26/new_note_pressed_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Notes-master/res/mipmap-hdpi/ic_launcher.webp b/src/Notes-master/res/mipmap-hdpi/ic_launcher.webp
index c209e78..178a6b1 100644
Binary files a/src/Notes-master/res/mipmap-hdpi/ic_launcher.webp and b/src/Notes-master/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/src/Notes-master/res/mipmap-hdpi/ic_launcher_foreground.webp b/src/Notes-master/res/mipmap-hdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..841c03e
Binary files /dev/null and b/src/Notes-master/res/mipmap-hdpi/ic_launcher_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-hdpi/ic_launcher_round.webp b/src/Notes-master/res/mipmap-hdpi/ic_launcher_round.webp
index b2dfe3d..af3aefe 100644
Binary files a/src/Notes-master/res/mipmap-hdpi/ic_launcher_round.webp and b/src/Notes-master/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/src/Notes-master/res/mipmap-hdpi/new_note_pressed.webp b/src/Notes-master/res/mipmap-hdpi/new_note_pressed.webp
new file mode 100644
index 0000000..aa6a253
Binary files /dev/null and b/src/Notes-master/res/mipmap-hdpi/new_note_pressed.webp differ
diff --git a/src/Notes-master/res/mipmap-hdpi/new_note_pressed_foreground.webp b/src/Notes-master/res/mipmap-hdpi/new_note_pressed_foreground.webp
new file mode 100644
index 0000000..8a39989
Binary files /dev/null and b/src/Notes-master/res/mipmap-hdpi/new_note_pressed_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-hdpi/new_note_pressed_round.webp b/src/Notes-master/res/mipmap-hdpi/new_note_pressed_round.webp
new file mode 100644
index 0000000..18386ae
Binary files /dev/null and b/src/Notes-master/res/mipmap-hdpi/new_note_pressed_round.webp differ
diff --git a/src/Notes-master/res/mipmap-mdpi/ic_launcher.webp b/src/Notes-master/res/mipmap-mdpi/ic_launcher.webp
index 4f0f1d6..c168ebb 100644
Binary files a/src/Notes-master/res/mipmap-mdpi/ic_launcher.webp and b/src/Notes-master/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/src/Notes-master/res/mipmap-mdpi/ic_launcher_foreground.webp b/src/Notes-master/res/mipmap-mdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..700da66
Binary files /dev/null and b/src/Notes-master/res/mipmap-mdpi/ic_launcher_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-mdpi/ic_launcher_round.webp b/src/Notes-master/res/mipmap-mdpi/ic_launcher_round.webp
index 62b611d..61e715a 100644
Binary files a/src/Notes-master/res/mipmap-mdpi/ic_launcher_round.webp and b/src/Notes-master/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/src/Notes-master/res/mipmap-mdpi/new_note_pressed.webp b/src/Notes-master/res/mipmap-mdpi/new_note_pressed.webp
new file mode 100644
index 0000000..9a95a3c
Binary files /dev/null and b/src/Notes-master/res/mipmap-mdpi/new_note_pressed.webp differ
diff --git a/src/Notes-master/res/mipmap-mdpi/new_note_pressed_foreground.webp b/src/Notes-master/res/mipmap-mdpi/new_note_pressed_foreground.webp
new file mode 100644
index 0000000..25fc6d4
Binary files /dev/null and b/src/Notes-master/res/mipmap-mdpi/new_note_pressed_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-mdpi/new_note_pressed_round.webp b/src/Notes-master/res/mipmap-mdpi/new_note_pressed_round.webp
new file mode 100644
index 0000000..1624ebf
Binary files /dev/null and b/src/Notes-master/res/mipmap-mdpi/new_note_pressed_round.webp differ
diff --git a/src/Notes-master/res/mipmap-xhdpi/ic_launcher.webp b/src/Notes-master/res/mipmap-xhdpi/ic_launcher.webp
index 948a307..73338a7 100644
Binary files a/src/Notes-master/res/mipmap-xhdpi/ic_launcher.webp and b/src/Notes-master/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/src/Notes-master/res/mipmap-xhdpi/ic_launcher_foreground.webp b/src/Notes-master/res/mipmap-xhdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..dd89d0d
Binary files /dev/null and b/src/Notes-master/res/mipmap-xhdpi/ic_launcher_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-xhdpi/ic_launcher_round.webp b/src/Notes-master/res/mipmap-xhdpi/ic_launcher_round.webp
index 1b9a695..cc41ce4 100644
Binary files a/src/Notes-master/res/mipmap-xhdpi/ic_launcher_round.webp and b/src/Notes-master/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/src/Notes-master/res/mipmap-xhdpi/new_note_pressed.webp b/src/Notes-master/res/mipmap-xhdpi/new_note_pressed.webp
new file mode 100644
index 0000000..ad9cc41
Binary files /dev/null and b/src/Notes-master/res/mipmap-xhdpi/new_note_pressed.webp differ
diff --git a/src/Notes-master/res/mipmap-xhdpi/new_note_pressed_foreground.webp b/src/Notes-master/res/mipmap-xhdpi/new_note_pressed_foreground.webp
new file mode 100644
index 0000000..3741967
Binary files /dev/null and b/src/Notes-master/res/mipmap-xhdpi/new_note_pressed_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-xhdpi/new_note_pressed_round.webp b/src/Notes-master/res/mipmap-xhdpi/new_note_pressed_round.webp
new file mode 100644
index 0000000..ad247c4
Binary files /dev/null and b/src/Notes-master/res/mipmap-xhdpi/new_note_pressed_round.webp differ
diff --git a/src/Notes-master/res/mipmap-xxhdpi/ic_launcher.webp b/src/Notes-master/res/mipmap-xxhdpi/ic_launcher.webp
index 28d4b77..ba4ea9c 100644
Binary files a/src/Notes-master/res/mipmap-xxhdpi/ic_launcher.webp and b/src/Notes-master/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/src/Notes-master/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/src/Notes-master/res/mipmap-xxhdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..052f962
Binary files /dev/null and b/src/Notes-master/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-xxhdpi/ic_launcher_round.webp b/src/Notes-master/res/mipmap-xxhdpi/ic_launcher_round.webp
index 9287f50..eec1094 100644
Binary files a/src/Notes-master/res/mipmap-xxhdpi/ic_launcher_round.webp and b/src/Notes-master/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/src/Notes-master/res/mipmap-xxhdpi/new_note_pressed.webp b/src/Notes-master/res/mipmap-xxhdpi/new_note_pressed.webp
new file mode 100644
index 0000000..9059c68
Binary files /dev/null and b/src/Notes-master/res/mipmap-xxhdpi/new_note_pressed.webp differ
diff --git a/src/Notes-master/res/mipmap-xxhdpi/new_note_pressed_foreground.webp b/src/Notes-master/res/mipmap-xxhdpi/new_note_pressed_foreground.webp
new file mode 100644
index 0000000..1f3c606
Binary files /dev/null and b/src/Notes-master/res/mipmap-xxhdpi/new_note_pressed_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-xxhdpi/new_note_pressed_round.webp b/src/Notes-master/res/mipmap-xxhdpi/new_note_pressed_round.webp
new file mode 100644
index 0000000..729d4d3
Binary files /dev/null and b/src/Notes-master/res/mipmap-xxhdpi/new_note_pressed_round.webp differ
diff --git a/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher.webp b/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher.webp
index aa7d642..442482d 100644
Binary files a/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher.webp and b/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
new file mode 100644
index 0000000..70bd95c
Binary files /dev/null and b/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher_round.webp b/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher_round.webp
index 9126ae3..7e2faf5 100644
Binary files a/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/src/Notes-master/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/src/Notes-master/res/mipmap-xxxhdpi/new_note_pressed.webp b/src/Notes-master/res/mipmap-xxxhdpi/new_note_pressed.webp
new file mode 100644
index 0000000..d1a4f99
Binary files /dev/null and b/src/Notes-master/res/mipmap-xxxhdpi/new_note_pressed.webp differ
diff --git a/src/Notes-master/res/mipmap-xxxhdpi/new_note_pressed_foreground.webp b/src/Notes-master/res/mipmap-xxxhdpi/new_note_pressed_foreground.webp
new file mode 100644
index 0000000..da77fe2
Binary files /dev/null and b/src/Notes-master/res/mipmap-xxxhdpi/new_note_pressed_foreground.webp differ
diff --git a/src/Notes-master/res/mipmap-xxxhdpi/new_note_pressed_round.webp b/src/Notes-master/res/mipmap-xxxhdpi/new_note_pressed_round.webp
new file mode 100644
index 0000000..5da155d
Binary files /dev/null and b/src/Notes-master/res/mipmap-xxxhdpi/new_note_pressed_round.webp differ
diff --git a/src/Notes-master/res/values-zh-rCN/strings.xml b/src/Notes-master/res/values-zh-rCN/strings.xml
index 09f75ed..80d29a2 100644
--- a/src/Notes-master/res/values-zh-rCN/strings.xml
+++ b/src/Notes-master/res/values-zh-rCN/strings.xml
@@ -17,7 +17,7 @@
- 便签
+ 小米便签
便签2x2
便签4x4
没有关联内容,点击新建便签。
diff --git a/src/Notes-master/src/net/micode/notes/data/Notes.java b/src/Notes-master/src/net/micode/notes/data/Notes.java
index 5b309f9..087d09e 100644
--- a/src/Notes-master/src/net/micode/notes/data/Notes.java
+++ b/src/Notes-master/src/net/micode/notes/data/Notes.java
@@ -34,6 +34,8 @@ public class Notes {
public static final int TYPE_FOLDER = 1;
// 2类型:系统文件夹
public static final int TYPE_SYSTEM = 2;
+ // 3类型:清单
+ public static final int TYPE_CHECKLIST = 3;
// 系统文件夹的 ID 定义。
// #ID_ROOT_FOLDER 默认根文件夹
@@ -47,12 +49,13 @@ public class Notes {
/**
* Intent Extra 键常量,用于在 Android 组件间通过 Intent 传递数据,包括:
- * 1. 提醒日期
+ * 1. 提醒日期
* 2. 背景颜色ID
* 3. 小部件ID
* 4. 小部件类型
* 5. 文件夹ID
* 6. 通话日期
+ * 7. 笔记类型
*/
public static final String INTENT_EXTRA_ALERT_DATE = "net.micode.notes.alert_date";
public static final String INTENT_EXTRA_BACKGROUND_ID = "net.micode.notes.background_color_id";
@@ -60,6 +63,7 @@ public class Notes {
public static final String INTENT_EXTRA_WIDGET_TYPE = "net.micode.notes.widget_type";
public static final String INTENT_EXTRA_FOLDER_ID = "net.micode.notes.folder_id";
public static final String INTENT_EXTRA_CALL_DATE = "net.micode.notes.call_date";
+ public static final String INTENT_EXTRA_NOTE_TYPE = "net.micode.notes.note_type";
// 无效的小部件类型 -1
public static final int TYPE_WIDGET_INVALIDE = -1;
@@ -93,7 +97,7 @@ public class Notes {
* 笔记表的列名定义接口
*/
public interface NoteColumns {
-
+
// 行的唯一ID
public static final String ID = "_id";
@@ -146,7 +150,7 @@ public class Notes {
public static final String VERSION = "version";
}
- /**
+ /**
* DataColumns 接口 - 便签数据表(data表)列定义
* 定义了便签详细内容的数据表列名和类型
* 使用MIME_TYPE字段区分不同类型的便签数据(文本便签、通话记录等)
@@ -196,7 +200,7 @@ public class Notes {
// 清单模式常量
public static final int MODE_CHECK_LIST = 1;
-
+
// 普通模式常量
public static final int MODE_NORMAL = 0;
diff --git a/src/Notes-master/src/net/micode/notes/model/ChecklistManager.java b/src/Notes-master/src/net/micode/notes/model/ChecklistManager.java
new file mode 100644
index 0000000..3acfedd
--- /dev/null
+++ b/src/Notes-master/src/net/micode/notes/model/ChecklistManager.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.micode.notes.model;
+
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.database.Cursor;
+
+import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.DataColumns;
+import net.micode.notes.data.Notes.DataConstants;
+import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.data.Notes.TextNote;
+
+/**
+ * 清单管理类
+ * 封装了清单相关的所有功能,包括清单的创建、查询、转换等
+ */
+public class ChecklistManager {
+ private static final String TAG = "ChecklistManager";
+ private ContentResolver mContentResolver;
+
+ /**
+ * 构造函数
+ * @param contentResolver 内容解析器
+ */
+ public ChecklistManager(ContentResolver contentResolver) {
+ mContentResolver = contentResolver;
+ }
+
+ /**
+ * 检查一个笔记是否为清单
+ * @param noteId 笔记ID
+ * @return 是否为清单
+ */
+ public boolean isChecklistNote(long noteId) {
+ // 使用ContentResolver查询笔记是否为清单
+ String selection = DataColumns.NOTE_ID + "=? AND " + DataColumns.MIME_TYPE + "=? AND " + DataColumns.DATA1 + "=? AND " + DataColumns.DATA2 + "=?";
+ String[] selectionArgs = {String.valueOf(noteId), DataConstants.NOTE, TextNote.MODE, String.valueOf(TextNote.MODE_CHECK_LIST)};
+
+ Cursor cursor = mContentResolver.query(Notes.CONTENT_DATA_URI, null, selection, selectionArgs, null);
+ boolean isChecklist = false;
+
+ if (cursor != null) {
+ isChecklist = cursor.moveToFirst();
+ cursor.close();
+ }
+
+ return isChecklist;
+ }
+
+ /**
+ * 创建清单笔记
+ * @param folderId 文件夹ID
+ * @param widgetId 小部件ID
+ * @param widgetType 小部件类型
+ * @param bgResId 背景资源ID
+ * @param context 上下文
+ * @return 创建的清单笔记
+ */
+ public WorkingNote createChecklistNote(long folderId, int widgetId, int widgetType, int bgResId, android.content.Context context) {
+ WorkingNote note = WorkingNote.createEmptyNote(context, folderId, widgetId, widgetType, bgResId);
+ note.setCheckListMode(TextNote.MODE_CHECK_LIST);
+ return note;
+ }
+
+ /**
+ * 为工作笔记设置清单类型
+ * @param workingNote 工作笔记
+ */
+ public void setChecklistType(WorkingNote workingNote) {
+ // 这里可以根据需要设置笔记类型
+ // workingNote.setNoteType(Notes.TYPE_CHECKLIST);
+ }
+
+ /**
+ * 将普通笔记转换为清单
+ * @param noteId 笔记ID
+ * @param context 上下文
+ * @return 是否转换成功
+ */
+ public boolean convertToChecklist(long noteId, android.content.Context context) {
+ WorkingNote note = WorkingNote.load(context, noteId);
+ if (note != null) {
+ note.setCheckListMode(TextNote.MODE_CHECK_LIST);
+ return note.saveNote();
+ }
+ return false;
+ }
+
+ /**
+ * 将清单转换为普通笔记
+ * @param noteId 笔记ID
+ * @param context 上下文
+ * @return 是否转换成功
+ */
+ public boolean convertToNormal(long noteId, android.content.Context context) {
+ WorkingNote note = WorkingNote.load(context, noteId);
+ if (note != null) {
+ note.setCheckListMode(TextNote.MODE_NORMAL);
+ return note.saveNote();
+ }
+ return false;
+ }
+
+ /**
+ * 获取清单笔记的选择条件
+ * @return SQL选择条件
+ */
+ public String getChecklistSelection() {
+ // 使用子查询来检查笔记是否为清单模式
+ return "EXISTS (SELECT 1 FROM note_data WHERE note_id = " + NoteColumns.ID +
+ " AND data1 = '" + TextNote.MODE + "' AND data2 = '" + String.valueOf(TextNote.MODE_CHECK_LIST) + "')";
+ }
+
+ /**
+ * 为Intent添加清单模式标记
+ * @param intent 要修改的Intent
+ * @param forceChecklist 是否强制进入清单模式
+ */
+ public void addChecklistModeToIntent(Intent intent, boolean forceChecklist) {
+ if (forceChecklist) {
+ intent.putExtra("FORCE_CHECKLIST_MODE", true);
+ }
+ }
+
+ /**
+ * 处理Intent中的清单模式标记,创建相应类型的笔记
+ * @param intent Intent对象
+ * @param workingNote 工作笔记对象
+ */
+ public void handleChecklistModeFromIntent(Intent intent, WorkingNote workingNote) {
+ boolean forceChecklistMode = intent.getBooleanExtra("FORCE_CHECKLIST_MODE", false);
+ if (forceChecklistMode) {
+ workingNote.setCheckListMode(TextNote.MODE_CHECK_LIST);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Notes-master/src/net/micode/notes/model/Note.java b/src/Notes-master/src/net/micode/notes/model/Note.java
index e5bc3cb..1f819a7 100644
--- a/src/Notes-master/src/net/micode/notes/model/Note.java
+++ b/src/Notes-master/src/net/micode/notes/model/Note.java
@@ -50,15 +50,16 @@ public class Note {
*
* @param context 上下文对象
* @param folderId 目标父文件夹ID
+ * @param type 笔记类型,默认是TYPE_NOTE
* @return 新创建的笔记ID(>0);失败抛出异常或返回0
*/
- public static synchronized long getNewNoteId(Context context, long folderId) {
+ public static synchronized long getNewNoteId(Context context, long folderId, int type) {
// 在数据库中创建新笔记:设置创建/修改时间、类型、父文件夹等初始值
ContentValues values = new ContentValues();
long createdTime = System.currentTimeMillis();
values.put(NoteColumns.CREATED_DATE, createdTime);
values.put(NoteColumns.MODIFIED_DATE, createdTime);
- values.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
+ values.put(NoteColumns.TYPE, type);
values.put(NoteColumns.LOCAL_MODIFIED, 1);
values.put(NoteColumns.PARENT_ID, folderId);
Uri uri = context.getContentResolver().insert(Notes.CONTENT_NOTE_URI, values);
@@ -76,6 +77,18 @@ public class Note {
return noteId;
}
+ /**
+ * 创建新笔记并返回ID。
+ * 重载方法,默认创建TYPE_NOTE类型的笔记
+ *
+ * @param context 上下文对象
+ * @param folderId 目标父文件夹ID
+ * @return 新创建的笔记ID(>0);失败抛出异常或返回0
+ */
+ public static synchronized long getNewNoteId(Context context, long folderId) {
+ return getNewNoteId(context, folderId, Notes.TYPE_NOTE);
+ }
+
/**
* 构造方法 - 初始化笔记对象
*/
diff --git a/src/Notes-master/src/net/micode/notes/model/WorkingNote.java b/src/Notes-master/src/net/micode/notes/model/WorkingNote.java
index 0078965..ea9b2a3 100644
--- a/src/Notes-master/src/net/micode/notes/model/WorkingNote.java
+++ b/src/Notes-master/src/net/micode/notes/model/WorkingNote.java
@@ -56,6 +56,7 @@ public class WorkingNote {
private static final String TAG = "WorkingNote"; // 日志标签
private boolean mIsDeleted; // 是否已删除
private NoteSettingChangedListener mNoteSettingStatusListener; // 笔记设置变化监听器
+ private int mNoteType; // 笔记类型(普通笔记/清单)
@@ -114,6 +115,7 @@ public class WorkingNote {
mIsDeleted = false;
mMode = 0;
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
+ mNoteType = Notes.TYPE_NOTE; // 默认创建普通笔记
}
/**
@@ -164,7 +166,7 @@ public class WorkingNote {
private void loadNoteData() {
Cursor cursor = mContext.getContentResolver().query(Notes.CONTENT_DATA_URI, DATA_PROJECTION,
DataColumns.NOTE_ID + "=?", new String[] {
- String.valueOf(mNoteId)
+ String.valueOf(mNoteId)
}, null);
if (cursor != null) {
@@ -200,7 +202,7 @@ public class WorkingNote {
* @return 工作笔记对象
*/
public static WorkingNote createEmptyNote(Context context, long folderId, int widgetId,
- int widgetType, int defaultBgColorId) {
+ int widgetType, int defaultBgColorId) {
WorkingNote note = new WorkingNote(context, folderId);
note.setBgColorId(defaultBgColorId);
note.setWidgetId(widgetId);
@@ -226,7 +228,14 @@ public class WorkingNote {
public synchronized boolean saveNote() {
if (isWorthSaving()) {
if (!existInDatabase()) {
- if ((mNoteId = Note.getNewNoteId(mContext, mFolderId)) == 0) {
+ // 根据当前模式设置笔记类型
+ int noteType = Notes.TYPE_NOTE;
+ if (mMode == TextNote.MODE_CHECK_LIST) {
+ noteType = Notes.TYPE_CHECKLIST;
+ }
+
+ // 使用指定的笔记类型创建新笔记
+ if ((mNoteId = Note.getNewNoteId(mContext, mFolderId, noteType)) == 0) {
Log.e(TAG, "Create new note fail with id:" + mNoteId);
return false;
}
@@ -299,7 +308,7 @@ public class WorkingNote {
mIsDeleted = mark;
if (mWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID
&& mWidgetType != Notes.TYPE_WIDGET_INVALIDE && mNoteSettingStatusListener != null) {
- mNoteSettingStatusListener.onWidgetChanged();
+ mNoteSettingStatusListener.onWidgetChanged();
}
}
diff --git a/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java b/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
index a3f1487..8c0b1ea 100644
--- a/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
+++ b/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
@@ -55,6 +55,7 @@ import android.widget.Toast;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.TextNote;
+import net.micode.notes.model.ChecklistManager;
import net.micode.notes.model.WorkingNote;
import net.micode.notes.model.WorkingNote.NoteSettingChangedListener;
import net.micode.notes.tool.DataUtils;
@@ -161,6 +162,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private LinearLayout mEditTextList; // 编辑文本列表(用于清单模式)
private String mUserQuery; // 用户查询字符串
private Pattern mPattern; // 正则表达式模式(用于高亮查询结果)
+ private ChecklistManager mChecklistManager; // 清单管理器(OMO)
/**
* 创建活动时调用
@@ -171,12 +173,16 @@ public class NoteEditActivity extends Activity implements OnClickListener,
super.onCreate(savedInstanceState);
this.setContentView(R.layout.note_edit); // 设置布局
+ initResources(); // 先初始化资源,再初始化活动状态(OMO)
+
+ // 初始化清单管理器
+ mChecklistManager = new ChecklistManager(getContentResolver());
+
// 如果没有保存的状态且无法初始化活动状态,则结束活动
if (savedInstanceState == null && !initActivityState(getIntent())) {
finish();
return;
}
- initResources(); // 初始化资源
}
/**
@@ -220,7 +226,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY);
}
- if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) {
+ if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE) && !DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_CHECKLIST)) {
Intent jump = new Intent(this, NotesListActivity.class);
startActivity(jump);
showToast(R.string.error_note_not_exist);
@@ -269,8 +275,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mWorkingNote.convertToCallNote(phoneNumber, callDate);
}
} else {
- mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType,
- bgResId);
+ mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId);
+
+ // 设置笔记类型
+ int noteType = intent.getIntExtra(Notes.INTENT_EXTRA_NOTE_TYPE, Notes.TYPE_NOTE);
+
+ // 使用ChecklistManager处理清单模式标记(OMO)
+ if (mChecklistManager != null) {
+ mChecklistManager.handleChecklistModeFromIntent(intent, mWorkingNote);
+ }
}
getWindow().setSoftInputMode(
@@ -302,7 +315,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
// 设置笔记编辑器的文本外观
mNoteEditor.setTextAppearance(this, TextAppearanceResources
.getTexAppearanceResource(mFontSizeId));
-
+
// 根据笔记模式设置显示方式
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
switchToListMode(mWorkingNote.getContent()); // 切换到清单模式
@@ -312,12 +325,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
// 将光标定位到文本末尾
mNoteEditor.setSelection(mNoteEditor.getText().length());
}
-
+
// 隐藏所有背景选择的选中状态
for (Integer id : sBgSelectorSelectionMap.keySet()) {
findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE);
}
-
+
// 设置头部视图和编辑器面板的背景
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
@@ -418,8 +431,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|| ev.getX() > (x + view.getWidth())
|| ev.getY() < y
|| ev.getY() > (y + view.getHeight())) {
- return false;
- }
+ return false;
+ }
return true;
}
@@ -438,7 +451,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteEditor = (EditText) findViewById(R.id.note_edit_view);
mNoteEditorPanel = findViewById(R.id.sv_note_edit);
mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector);
-
+
// 为所有背景选择按钮设置点击监听器
for (int id : sBgSelectorBtnsMap.keySet()) {
ImageView iv = (ImageView) findViewById(id);
@@ -446,17 +459,17 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
mFontSizeSelector = findViewById(R.id.font_size_selector);
-
+
// 为所有字体大小选择按钮设置点击监听器
for (int id : sFontSizeBtnsMap.keySet()) {
View view = findViewById(id);
view.setOnClickListener(this);
};
-
+
// 初始化共享偏好设置和字体大小
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE);
-
+
/**
* HACKME: Fix bug of store the resource id in shared preference.
* The id may larger than the length of resources, in this case,
@@ -465,7 +478,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE;
}
-
+
mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list);
}
@@ -488,7 +501,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
*/
private void updateWidget() {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
-
+
// 根据小部件类型设置对应的小部件提供器
if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) {
intent.setClass(this, NoteWidgetProvider_2x.class);
@@ -500,7 +513,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
- mWorkingNote.getWidgetId()
+ mWorkingNote.getWidgetId()
});
sendBroadcast(intent); // 发送广播更新小部件
@@ -531,7 +544,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mFontSizeId = sFontSizeBtnsMap.get(id);
mSharedPrefs.edit().putInt(PREFERENCE_FONT_SIZE, mFontSizeId).commit();
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
-
+
// 根据当前模式更新字体大小
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
getWorkingText();
@@ -857,6 +870,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* @param text 要转换的文本内容
*/
private void switchToListMode(String text) {
+ // 处理null文本,避免空指针异常(OMO)
+ if (text == null) {
+ text = "";
+ }
+
mEditTextList.removeAllViews(); // 清空编辑文本列表
String[] items = text.split("\n"); // 按行分割文本
int index = 0;
@@ -909,7 +927,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
-
+
// 设置复选框的选中状态变化监听器
CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item));
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@@ -964,14 +982,31 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* @param newMode 新模式
*/
public void onCheckListModeChanged(int oldMode, int newMode) {
+ // 添加null检查,避免在mNoteEditor初始化前调用导致闪退
+ if (mNoteEditor == null || mEditTextList == null) {
+ return;
+ }
+
+ String text = "";
if (newMode == TextNote.MODE_CHECK_LIST) {
- switchToListMode(mNoteEditor.getText().toString());
+ // 安全获取文本,避免空指针异常(OMO)
+ if (mNoteEditor.getText() != null) {
+ text = mNoteEditor.getText().toString();
+ }
+ switchToListMode(text);
} else {
if (!getWorkingText()) {
- mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ",
- ""));
+ String content = mWorkingNote.getContent();
+ if (content != null) {
+ mWorkingNote.setWorkingText(content.replace(TAG_UNCHECKED + " ", ""));
+ }
+ }
+ String content = mWorkingNote.getContent();
+ if (content != null) {
+ mNoteEditor.setText(getHighlightQueryResult(content, mUserQuery));
+ } else {
+ mNoteEditor.setText("");
}
- mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
mEditTextList.setVisibility(View.GONE);
mNoteEditor.setVisibility(View.VISIBLE);
}
diff --git a/src/Notes-master/src/net/micode/notes/ui/NoteItemData.java b/src/Notes-master/src/net/micode/notes/ui/NoteItemData.java
index 14f60be..47b7eb5 100644
--- a/src/Notes-master/src/net/micode/notes/ui/NoteItemData.java
+++ b/src/Notes-master/src/net/micode/notes/ui/NoteItemData.java
@@ -36,18 +36,18 @@ import net.micode.notes.tool.DataUtils;
public class NoteItemData {
/** 数据库查询投影数组 */
static final String [] PROJECTION = new String [] {
- NoteColumns.ID, // 笔记ID
- NoteColumns.ALERTED_DATE, // 提醒日期
- NoteColumns.BG_COLOR_ID, // 背景颜色ID
- NoteColumns.CREATED_DATE, // 创建日期
- NoteColumns.HAS_ATTACHMENT, // 是否有附件
- NoteColumns.MODIFIED_DATE, // 修改日期
- NoteColumns.NOTES_COUNT, // 笔记数量
- NoteColumns.PARENT_ID, // 父文件夹ID
- NoteColumns.SNIPPET, // 笔记摘要
- NoteColumns.TYPE, // 笔记类型
- NoteColumns.WIDGET_ID, // 小部件ID
- NoteColumns.WIDGET_TYPE, // 小部件类型
+ NoteColumns.ID, // 笔记ID
+ NoteColumns.ALERTED_DATE, // 提醒日期
+ NoteColumns.BG_COLOR_ID, // 背景颜色ID
+ NoteColumns.CREATED_DATE, // 创建日期
+ NoteColumns.HAS_ATTACHMENT, // 是否有附件
+ NoteColumns.MODIFIED_DATE, // 修改日期
+ NoteColumns.NOTES_COUNT, // 笔记数量
+ NoteColumns.PARENT_ID, // 父文件夹ID
+ NoteColumns.SNIPPET, // 笔记摘要
+ NoteColumns.TYPE, // 笔记类型
+ NoteColumns.WIDGET_ID, // 小部件ID
+ NoteColumns.WIDGET_TYPE, // 小部件类型
};
/** 笔记ID列索引 */
@@ -103,6 +103,10 @@ public class NoteItemData {
private String mName;
/** 电话号码(用于通话记录) */
private String mPhoneNumber;
+ /** 清单项目完成状态 */
+ private boolean mIsChecked;
+ /** 原始带标记的摘要 */
+ private String mOriginalSnippet;
/** 是否为最后一项 */
private boolean mIsLastItem;
@@ -129,10 +133,19 @@ public class NoteItemData {
mModifiedDate = cursor.getLong(MODIFIED_DATE_COLUMN);
mNotesCount = cursor.getInt(NOTES_COUNT_COLUMN);
mParentId = cursor.getLong(PARENT_ID_COLUMN);
- mSnippet = cursor.getString(SNIPPET_COLUMN);
- // 移除复选框标签
- mSnippet = mSnippet.replace(NoteEditActivity.TAG_CHECKED, "").replace(
- NoteEditActivity.TAG_UNCHECKED, "");
+ mOriginalSnippet = cursor.getString(SNIPPET_COLUMN);
+ mSnippet = mOriginalSnippet;
+
+ // 解析完成状态
+ mIsChecked = false;
+ if (mSnippet.startsWith(NoteEditActivity.TAG_CHECKED)) {
+ mIsChecked = true;
+ mSnippet = mSnippet.substring(NoteEditActivity.TAG_CHECKED.length()).trim();
+ } else if (mSnippet.startsWith(NoteEditActivity.TAG_UNCHECKED)) {
+ mIsChecked = false;
+ mSnippet = mSnippet.substring(NoteEditActivity.TAG_UNCHECKED.length()).trim();
+ }
+
mType = cursor.getInt(TYPE_COLUMN);
mWidgetId = cursor.getInt(WIDGET_ID_COLUMN);
mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN);
@@ -167,8 +180,8 @@ public class NoteItemData {
mIsMultiNotesFollowingFolder = false;
mIsOneNoteFollowingFolder = false;
- // 如果是笔记类型且不是第一项,检查前一项是否为文件夹
- if (mType == Notes.TYPE_NOTE && !mIsFirstItem) {
+ // 如果是笔记或清单类型且不是第一项,检查前一项是否为文件夹
+ if ((mType == Notes.TYPE_NOTE || mType == Notes.TYPE_CHECKLIST) && !mIsFirstItem) {
int position = cursor.getPosition();
if (cursor.moveToPrevious()) {
if (cursor.getInt(TYPE_COLUMN) == Notes.TYPE_FOLDER
@@ -356,6 +369,30 @@ public class NoteItemData {
return (mParentId == Notes.ID_CALL_RECORD_FOLDER && !TextUtils.isEmpty(mPhoneNumber));
}
+ /**
+ * 获取清单项目完成状态
+ * @return true表示已完成,false表示未完成
+ */
+ public boolean isChecked() {
+ return mIsChecked;
+ }
+
+ /**
+ * 设置清单项目完成状态
+ * @param checked 完成状态
+ */
+ public void setChecked(boolean checked) {
+ mIsChecked = checked;
+ }
+
+ /**
+ * 获取原始带标记的摘要
+ * @return 原始摘要
+ */
+ public String getOriginalSnippet() {
+ return mOriginalSnippet;
+ }
+
/**
* 从Cursor中获取笔记类型
* @param cursor 包含笔记数据的Cursor
diff --git a/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java b/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java
index 31b61b7..9e69b65 100644
--- a/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java
+++ b/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java
@@ -63,7 +63,9 @@ import android.widget.Toast;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
+import net.micode.notes.data.Notes.TextNote;
import net.micode.notes.gtask.remote.GTaskSyncService;
+import net.micode.notes.model.ChecklistManager;
import net.micode.notes.model.WorkingNote;
import net.micode.notes.tool.BackupUtils;
import net.micode.notes.tool.DataUtils;
@@ -78,6 +80,10 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
+import android.os.Build;
+import android.view.ViewConfiguration;
+import java.lang.reflect.Field;
+
/**
* 笔记列表活动 - 负责显示和管理笔记列表
* 提供笔记的创建、编辑、删除、移动等功能
@@ -119,6 +125,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private long mCurrentFolderId; // 当前文件夹ID
private ContentResolver mContentResolver; // 内容解析器
private ModeCallback mModeCallBack; // 多选模式回调
+ private boolean mIsChecklistMode; // 是否为清单模式(OMO)
+ private Button mNoteModeButton; // 笔记模式按钮(OMO)
+ private Button mChecklistModeButton; // 清单模式按钮(OMO)
+ private ChecklistManager mChecklistManager; // 清单管理器(OMO)
private static final String TAG = "NotesListActivity"; // 日志标签
public static final int NOTES_LISTVIEW_SCROLL_RATE = 30;// 笔记列表滚动速率
@@ -139,9 +149,30 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ // 隐藏标题栏OMO
+ if (getActionBar() != null) {
+ getActionBar().hide();
+ }
+
setContentView(R.layout.note_list); // 设置布局
initResources(); // 初始化资源
+ // 隐藏底部虚拟菜单按钮OMO
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ ViewConfiguration config = ViewConfiguration.get(this);
+ Field menuKeyField = null;
+ try {
+ menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
+ if (menuKeyField != null) {
+ menuKeyField.setAccessible(true);
+ menuKeyField.setBoolean(config, false);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+
// 首次进入时插入“介绍”笔记
setAppInfoFromRawRes(); // 设置应用信息(首次使用时添加介绍笔记)
}
@@ -158,7 +189,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
-/**
+ /**
* 从原始资源文件中设置应用介绍信息
* 当用户首次使用应用时,添加介绍笔记
*/
@@ -168,7 +199,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
StringBuilder sb = new StringBuilder();
InputStream in = null;
try {
- in = getResources().openRawResource(R.raw.introduction);
+ in = getResources().openRawResource(R.raw.introduction);
if (in != null) {
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
@@ -218,7 +249,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
startAsyncNotesListQuery();
}
-/**
+ /**
* 初始化资源
* 设置内容解析器、异步查询处理器、列表适配器等
*/
@@ -227,8 +258,6 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver());
mCurrentFolderId = Notes.ID_ROOT_FOLDER;
mNotesListView = (ListView) findViewById(R.id.notes_list);
- mNotesListView.addFooterView(LayoutInflater.from(this).inflate(R.layout.note_list_footer, null),
- null, false);
mNotesListView.setOnItemClickListener(new OnListItemClickListener());
mNotesListView.setOnItemLongClickListener(this);
mNotesListAdapter = new NotesListAdapter(this);
@@ -242,9 +271,16 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mTitleBar = (TextView) findViewById(R.id.tv_title_bar);
mState = ListEditState.NOTE_LIST;
mModeCallBack = new ModeCallback();
+
+ // 初始化模式切换按钮和清单管理器(OMO)
+ mNoteModeButton = (Button) findViewById(R.id.btn_note_mode);
+ mChecklistModeButton = (Button) findViewById(R.id.btn_checklist_mode);
+ mIsChecklistMode = false;
+ updateModeButtons();
+ mChecklistManager = new ChecklistManager(mContentResolver);
}
-/**
+ /**
* 多选模式回调类 - 处理笔记的多选操作
* 实现了多选模式下的菜单创建、选择状态变化等功能
*/
@@ -343,7 +379,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
* 更新适配器中的选择状态并刷新菜单
*/
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
- boolean checked) {
+ boolean checked) {
mNotesListAdapter.setCheckedItem(position, checked);
updateMenu();
}
@@ -366,14 +402,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
builder.setTitle(getString(R.string.alert_title_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setMessage(getString(R.string.alert_message_delete_notes,
- mNotesListAdapter.getSelectedCount()));
+ mNotesListAdapter.getSelectedCount()));
builder.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog,
- int which) {
- batchDelete(); // 执行批量删除
- }
- });
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int which) {
+ batchDelete(); // 执行批量删除
+ }
+ });
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
break;
@@ -388,7 +424,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
-/**
+ /**
* 新建笔记按钮的触摸监听器
* 处理特殊的触摸事件分发逻辑
*/
@@ -445,20 +481,41 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
};
-/**
+ /**
* 开始异步查询笔记列表
* 根据当前文件夹ID选择不同的查询条件
*/
private void startAsyncNotesListQuery() {
- String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION
- : NORMAL_SELECTION;
+ String selection;
+ String[] selectionArgs;
+
+ if (mCurrentFolderId == Notes.ID_ROOT_FOLDER) {
+ if (mIsChecklistMode) {
+ // 根文件夹下的清单模式:只显示清单类型的笔记
+ selection = "(" + NoteColumns.TYPE + "=" + Notes.TYPE_CHECKLIST + " AND " + NoteColumns.PARENT_ID + "=?)" +
+ " OR (" + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " + NoteColumns.NOTES_COUNT + ">0)";
+ } else {
+ // 根文件夹下的笔记模式:显示文件夹、普通笔记和非空通话记录文件夹
+ selection = "(" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?)" +
+ " OR (" + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " + NoteColumns.NOTES_COUNT + ">0)";
+ }
+ } else {
+ if (mIsChecklistMode) {
+ // 普通文件夹下的清单模式:只显示清单类型的笔记
+ selection = NoteColumns.PARENT_ID + "=? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_CHECKLIST;
+ } else {
+ // 普通文件夹下的笔记模式:只显示普通笔记
+ selection = NoteColumns.PARENT_ID + "=? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE;
+ }
+ }
+
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[] {
- String.valueOf(mCurrentFolderId)
+ String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
-/**
+ /**
* 后台查询处理器 - 处理异步数据库查询
*/
private final class BackgroundQueryHandler extends AsyncQueryHandler {
@@ -491,7 +548,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
-/**
+ /**
* 显示文件夹列表菜单
* 用于选择移动笔记的目标文件夹
*/
@@ -516,7 +573,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
builder.show();
}
-/**
+ /**
* 创建新笔记
* 跳转到笔记编辑界面
*/
@@ -524,10 +581,25 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mCurrentFolderId);
+
+ // 设置笔记类型
+ if (mIsChecklistMode) {
+ // 清单模式:创建清单类型的笔记
+ intent.putExtra(Notes.INTENT_EXTRA_NOTE_TYPE, Notes.TYPE_CHECKLIST);
+ } else {
+ // 笔记模式:创建普通笔记类型
+ intent.putExtra(Notes.INTENT_EXTRA_NOTE_TYPE, Notes.TYPE_NOTE);
+ }
+
+ // 如果是清单模式,使用ChecklistManager添加清单模式标记
+ if (mIsChecklistMode && mChecklistManager != null) {
+ mChecklistManager.addChecklistModeToIntent(intent, true);
+ }
+
this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE);
}
-/**
+ /**
* 批量删除笔记
* 在同步模式下将笔记移动到回收站,非同步模式下直接删除
*/
@@ -568,7 +640,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}.execute();
}
-/**
+ /**
* 删除文件夹
* 在同步模式下将文件夹移动到回收站,非同步模式下直接删除
*/
@@ -599,7 +671,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
-/**
+ /**
* 打开笔记
* 跳转到笔记编辑界面查看/编辑笔记
*/
@@ -610,7 +682,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE);
}
-/**
+ /**
* 打开文件夹
* 更新当前文件夹ID并重新查询笔记列表
*/
@@ -631,7 +703,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
mTitleBar.setVisibility(View.VISIBLE);
}
-/**
+ /**
* 处理点击事件
* 当前只处理新建笔记按钮的点击
*/
@@ -640,12 +712,90 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
case R.id.btn_new_note:
createNewNote();
break;
+
default:
break;
}
}
+ /**
+ * 显示自定义菜单
+ * OMO
+ */
+ public void showCustomMenu(View view) {
+ PopupMenu popupMenu = new PopupMenu(this, view);
+ popupMenu.inflate(R.menu.note_list); // 加载原有菜单资源
-/**
+ // 设置菜单点击事件
+ popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ // 调用原有的菜单处理逻辑
+ return onOptionsItemSelected(item);
+ }
+ });
+
+ popupMenu.show();
+ }
+
+ /**
+ * 更新模式按钮样式
+ * 根据当前模式更新按钮的背景色和文字颜色
+ * OMO
+ */
+ private void updateModeButtons() {
+ if (mIsChecklistMode) {
+ // 清单模式下,清单按钮高亮
+ mChecklistModeButton.setBackgroundColor(0xFF007AFF);
+ mChecklistModeButton.setTextColor(0xFFFFFFFF);
+ mNoteModeButton.setBackgroundColor(0xFFFFFFFF);
+ mNoteModeButton.setTextColor(0xFF000000);
+ } else {
+ // 笔记模式下,笔记按钮高亮
+ mNoteModeButton.setBackgroundColor(0xFF007AFF);
+ mNoteModeButton.setTextColor(0xFFFFFFFF);
+ mChecklistModeButton.setBackgroundColor(0xFFFFFFFF);
+ mChecklistModeButton.setTextColor(0xFF000000);
+ }
+ }
+
+ /**
+ * 切换到笔记模式
+ * @param view 点击的视图
+ * OMO
+ */
+ public void switchToNoteMode(View view) {
+ mIsChecklistMode = false;
+ updateModeButtons();
+
+ // 更新适配器模式
+ if (mNotesListAdapter != null) {
+ mNotesListAdapter.setChecklistMode(false);
+ }
+
+ // 查询笔记列表
+ startAsyncNotesListQuery();
+ }
+
+ /**
+ * 切换到清单模式
+ * 点击时切换到清单模式并显示清单列表
+ * @param view 点击的视图
+ * OMO
+ */
+ public void switchToChecklistMode(View view) {
+ mIsChecklistMode = true;
+ updateModeButtons();
+
+ // 更新适配器模式
+ if (mNotesListAdapter != null) {
+ mNotesListAdapter.setChecklistMode(true);
+ }
+
+ // 查询清单列表
+ startAsyncNotesListQuery();
+ }
+
+ /**
* 显示软键盘
*/
private void showSoftInput() {
@@ -655,7 +805,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
-/**
+ /**
* 隐藏软键盘
*/
private void hideSoftInput(View view) {
@@ -663,7 +813,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
-/**
+ /**
* 显示创建或修改文件夹的对话框
* @param create 是否为创建文件夹模式
*/
@@ -712,7 +862,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
values.put(NoteColumns.LOCAL_MODIFIED, 1);
mContentResolver.update(Notes.CONTENT_NOTE_URI, values, NoteColumns.ID
+ "=?", new String[] {
- String.valueOf(mFocusNoteDataItem.getId())
+ String.valueOf(mFocusNoteDataItem.getId())
});
}
} else if (!TextUtils.isEmpty(name)) {
@@ -780,7 +930,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
}
-/**
+ /**
* 更新小部件
* 根据小部件类型发送相应的广播更新
*/
@@ -796,14 +946,14 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
}
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
- appWidgetId
+ appWidgetId
});
sendBroadcast(intent);
setResult(RESULT_OK, intent);
}
-/**
+ /**
* 文件夹上下文菜单监听器
* 创建文件夹的上下文菜单
*/
@@ -939,7 +1089,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
startSearch(null, false, null /* appData */, false);
return true;
}
-
+ /**
+ * 处理搜索按钮的点击事件
+ * @param view 点击的视图
+ * OMO
+ */
+ public void handleSearchClick(View view) {
+ // 调用系统搜索方法
+ onSearchRequested();
+ }
private void exportNoteToText() {
final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this);
new AsyncTask() {
@@ -998,7 +1156,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
if (view instanceof NotesListItem) {
NoteItemData item = ((NotesListItem) view).getItemData();
if (mNotesListAdapter.isInChoiceMode()) {
- if (item.getType() == Notes.TYPE_NOTE) {
+ if (item.getType() == Notes.TYPE_NOTE || item.getType() == Notes.TYPE_CHECKLIST) {
position = position - mNotesListView.getHeaderViewsCount();
mModeCallBack.onItemCheckedStateChanged(null, position, id,
!mNotesListAdapter.isSelectedItem(position));
@@ -1011,18 +1169,18 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
if (item.getType() == Notes.TYPE_FOLDER
|| item.getType() == Notes.TYPE_SYSTEM) {
openFolder(item);
- } else if (item.getType() == Notes.TYPE_NOTE) {
+ } else if (item.getType() == Notes.TYPE_NOTE || item.getType() == Notes.TYPE_CHECKLIST) {
openNode(item);
} else {
- Log.e(TAG, "Wrong note type in NOTE_LIST");
+ Log.e(TAG, "Wrong note type in NOTE_LIST: " + item.getType());
}
break;
case SUB_FOLDER:
case CALL_RECORD_FOLDER:
- if (item.getType() == Notes.TYPE_NOTE) {
+ if (item.getType() == Notes.TYPE_NOTE || item.getType() == Notes.TYPE_CHECKLIST) {
openNode(item);
} else {
- Log.e(TAG, "Wrong note type in SUB_FOLDER");
+ Log.e(TAG, "Wrong note type in SUB_FOLDER: " + item.getType());
}
break;
default:
@@ -1036,7 +1194,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
private void startQueryDestinationFolders() {
String selection = NoteColumns.TYPE + "=? AND " + NoteColumns.PARENT_ID + "<>? AND " + NoteColumns.ID + "<>?";
selection = (mState == ListEditState.NOTE_LIST) ? selection:
- "(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")";
+ "(" + selection + ") OR (" + NoteColumns.ID + "=" + Notes.ID_ROOT_FOLDER + ")";
mBackgroundQueryHandler.startQuery(FOLDER_LIST_QUERY_TOKEN,
null,
@@ -1054,7 +1212,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
public boolean onItemLongClick(AdapterView> parent, View view, int position, long id) {
if (view instanceof NotesListItem) {
mFocusNoteDataItem = ((NotesListItem) view).getItemData();
- if (mFocusNoteDataItem.getType() == Notes.TYPE_NOTE && !mNotesListAdapter.isInChoiceMode()) {
+ if ((mFocusNoteDataItem.getType() == Notes.TYPE_NOTE || mFocusNoteDataItem.getType() == Notes.TYPE_CHECKLIST) && !mNotesListAdapter.isInChoiceMode()) {
if (mNotesListView.startActionMode(mModeCallBack) != null) {
mModeCallBack.onItemCheckedStateChanged(null, position, id, true);
mNotesListView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
diff --git a/src/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java b/src/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java
index 3ca6cb2..4fb993c 100644
--- a/src/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java
+++ b/src/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java
@@ -16,6 +16,8 @@
package net.micode.notes.ui;
+import android.content.ContentResolver;
+import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;
@@ -24,6 +26,7 @@ import android.view.ViewGroup;
import android.widget.CursorAdapter;
import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.NoteColumns;
import java.util.Collection;
import java.util.HashMap;
@@ -49,6 +52,8 @@ public class NotesListAdapter extends CursorAdapter {
private int mNotesCount;
/** 是否处于选择模式 */
private boolean mChoiceMode;
+ /** 是否处于清单模式 */
+ private boolean mIsChecklistMode;
/**
* 应用小部件属性类
@@ -70,6 +75,16 @@ public class NotesListAdapter extends CursorAdapter {
mSelectedIndex = new HashMap();
mContext = context;
mNotesCount = 0;
+ mIsChecklistMode = false;
+ }
+
+ /**
+ * 设置是否为清单模式
+ * @param isChecklistMode 是否为清单模式
+ */
+ public void setChecklistMode(boolean isChecklistMode) {
+ mIsChecklistMode = isChecklistMode;
+ notifyDataSetChanged();
}
/**
@@ -95,8 +110,90 @@ public class NotesListAdapter extends CursorAdapter {
public void bindView(View view, Context context, Cursor cursor) {
if (view instanceof NotesListItem) {
NoteItemData itemData = new NoteItemData(context, cursor);
- ((NotesListItem) view).bind(context, itemData, mChoiceMode,
- isSelectedItem(cursor.getPosition()));
+ NotesListItem notesListItem = (NotesListItem) view;
+
+ // 绑定数据,传递当前模式
+ notesListItem.bind(context, itemData, mChoiceMode,
+ isSelectedItem(cursor.getPosition()), mIsChecklistMode);
+
+ // 设置标题变更监听器
+ notesListItem.setOnTitleChangedListener(new NotesListItem.OnTitleChangedListener() {
+ @Override
+ public void onTitleChanged(long noteId, String newTitle) {
+ updateNoteTitle(noteId, newTitle);
+ }
+ });
+
+ // 设置完成状态变更监听器
+ notesListItem.setOnCheckStatusChangedListener(new NotesListItem.OnCheckStatusChangedListener() {
+ @Override
+ public void onCheckStatusChanged(long noteId, boolean isChecked) {
+ updateNoteCheckStatus(noteId, isChecked);
+ }
+ });
+ }
+ }
+
+ /**
+ * 更新笔记标题
+ * @param noteId 笔记ID
+ * @param newTitle 新标题
+ */
+ private void updateNoteTitle(long noteId, String newTitle) {
+ // 使用ContentResolver更新笔记标题
+ ContentValues values = new ContentValues();
+ values.put(NoteColumns.SNIPPET, newTitle);
+
+ mContext.getContentResolver().update(
+ Notes.CONTENT_NOTE_URI,
+ values,
+ NoteColumns.ID + "=?",
+ new String[]{String.valueOf(noteId)});
+ }
+
+ /**
+ * 更新清单项目完成状态
+ * @param noteId 笔记ID
+ * @param isChecked 完成状态
+ */
+ private void updateNoteCheckStatus(long noteId, boolean isChecked) {
+ // 查询当前笔记的内容
+ Cursor cursor = mContext.getContentResolver().query(
+ Notes.CONTENT_NOTE_URI,
+ new String[]{NoteColumns.SNIPPET},
+ NoteColumns.ID + "=?",
+ new String[]{String.valueOf(noteId)},
+ null);
+
+ if (cursor != null && cursor.moveToFirst()) {
+ String currentSnippet = cursor.getString(0);
+ cursor.close();
+
+ // 移除旧的标记
+ String contentWithoutMark = currentSnippet;
+ if (contentWithoutMark.startsWith(NoteEditActivity.TAG_CHECKED)) {
+ contentWithoutMark = contentWithoutMark.substring(NoteEditActivity.TAG_CHECKED.length()).trim();
+ } else if (contentWithoutMark.startsWith(NoteEditActivity.TAG_UNCHECKED)) {
+ contentWithoutMark = contentWithoutMark.substring(NoteEditActivity.TAG_UNCHECKED.length()).trim();
+ }
+
+ // 添加新的标记
+ String newSnippet;
+ if (isChecked) {
+ newSnippet = NoteEditActivity.TAG_CHECKED + " " + contentWithoutMark;
+ } else {
+ newSnippet = NoteEditActivity.TAG_UNCHECKED + " " + contentWithoutMark;
+ }
+
+ // 更新数据库
+ ContentValues values = new ContentValues();
+ values.put(NoteColumns.SNIPPET, newSnippet);
+
+ mContext.getContentResolver().update(
+ Notes.CONTENT_NOTE_URI,
+ values,
+ NoteColumns.ID + "=?",
+ new String[]{String.valueOf(noteId)});
}
}
@@ -135,8 +232,9 @@ public class NotesListAdapter extends CursorAdapter {
Cursor cursor = getCursor();
for (int i = 0; i < getCount(); i++) {
if (cursor.moveToPosition(i)) {
- // 只处理类型为笔记的项
- if (NoteItemData.getNoteType(cursor) == Notes.TYPE_NOTE) {
+ // 处理类型为笔记或清单的项
+ int type = NoteItemData.getNoteType(cursor);
+ if (type == Notes.TYPE_NOTE || type == Notes.TYPE_CHECKLIST) {
setCheckedItem(i, checked);
}
}
@@ -244,15 +342,16 @@ public class NotesListAdapter extends CursorAdapter {
/**
* 计算笔记总数
- * 遍历所有游标项,统计类型为笔记的项的数量
+ * 遍历所有游标项,统计类型为笔记或清单的项的数量
*/
private void calcNotesCount() {
mNotesCount = 0;
for (int i = 0; i < getCount(); i++) {
Cursor c = (Cursor) getItem(i);
if (c != null) {
- // 只统计类型为笔记的项
- if (NoteItemData.getNoteType(c) == Notes.TYPE_NOTE) {
+ // 统计类型为笔记或清单的项
+ int type = NoteItemData.getNoteType(c);
+ if (type == Notes.TYPE_NOTE || type == Notes.TYPE_CHECKLIST) {
mNotesCount++;
}
} else {
diff --git a/src/Notes-master/src/net/micode/notes/ui/NotesListItem.java b/src/Notes-master/src/net/micode/notes/ui/NotesListItem.java
index 8936af6..19d99a9 100644
--- a/src/Notes-master/src/net/micode/notes/ui/NotesListItem.java
+++ b/src/Notes-master/src/net/micode/notes/ui/NotesListItem.java
@@ -17,15 +17,24 @@
package net.micode.notes.ui;
import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.text.Editable;
+import android.text.TextWatcher;
import android.text.format.DateUtils;
+import android.view.MotionEvent;
import android.view.View;
+import android.view.inputmethod.InputMethodManager;
import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
+import net.micode.notes.data.Notes.TextNote;
import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.ResourceParser.NoteItemBgResources;
@@ -50,6 +59,48 @@ public class NotesListItem extends LinearLayout {
private NoteItemData mItemData;
/** 复选框(用于选择模式) */
private CheckBox mCheckBox;
+ /** 清单标题编辑框 */
+ private EditText mChecklistTitle;
+ /** 清单状态图标 */
+ private ImageView mChecklistStatus;
+ /** 上下文 */
+ private Context mContext;
+ /** 当前是否为清单模式 */
+ private boolean mIsChecklistMode;
+ /** 标题监听器,用于保存清单标题变更 */
+ private OnTitleChangedListener mOnTitleChangedListener;
+ /** 完成状态监听器,用于保存清单项目完成状态变更 */
+ private OnCheckStatusChangedListener mOnCheckStatusChangedListener;
+
+ /**
+ * 标题变更监听器接口
+ */
+ public interface OnTitleChangedListener {
+ void onTitleChanged(long noteId, String newTitle);
+ }
+
+ /**
+ * 完成状态变更监听器接口
+ */
+ public interface OnCheckStatusChangedListener {
+ void onCheckStatusChanged(long noteId, boolean isChecked);
+ }
+
+ /**
+ * 设置标题变更监听器
+ * @param listener 监听器
+ */
+ public void setOnTitleChangedListener(OnTitleChangedListener listener) {
+ mOnTitleChangedListener = listener;
+ }
+
+ /**
+ * 设置完成状态变更监听器
+ * @param listener 监听器
+ */
+ public void setOnCheckStatusChangedListener(OnCheckStatusChangedListener listener) {
+ mOnCheckStatusChangedListener = listener;
+ }
/**
* 创建一个笔记列表项视图实例
@@ -57,6 +108,7 @@ public class NotesListItem extends LinearLayout {
*/
public NotesListItem(Context context) {
super(context);
+ mContext = context;
// 填充布局
inflate(context, R.layout.note_item, this);
// 获取视图组件
@@ -65,6 +117,30 @@ public class NotesListItem extends LinearLayout {
mTime = (TextView) findViewById(R.id.tv_time);
mCallName = (TextView) findViewById(R.id.tv_name);
mCheckBox = (CheckBox) findViewById(android.R.id.checkbox);
+ // 初始化清单相关组件
+ mChecklistTitle = (EditText) findViewById(R.id.et_checklist_title);
+ mChecklistStatus = (ImageView) findViewById(R.id.iv_checklist_status);
+
+ // 设置清单标题编辑框的文本变更监听器
+ mChecklistTitle.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ // 文本变更前的处理
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ // 文本变更时的处理
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ // 文本变更后的处理,保存新标题
+ if (mItemData != null && mOnTitleChangedListener != null) {
+ mOnTitleChangedListener.onTitleChanged(mItemData.getId(), s.toString());
+ }
+ }
+ });
}
/**
@@ -75,16 +151,31 @@ public class NotesListItem extends LinearLayout {
* @param checked 是否被选中
*/
public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) {
- // 处理选择模式下的复选框显示
- if (choiceMode && data.getType() == Notes.TYPE_NOTE) {
- mCheckBox.setVisibility(View.VISIBLE);
- mCheckBox.setChecked(checked);
- } else {
- mCheckBox.setVisibility(View.GONE);
- }
+ bind(context, data, choiceMode, checked, false);
+ }
+
+ /**
+ * 将笔记数据绑定到视图
+ * @param context 上下文
+ * @param data 笔记项数据
+ * @param choiceMode 是否为选择模式
+ * @param checked 是否被选中
+ * @param isChecklistMode 是否为清单模式
+ */
+ public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked, boolean isChecklistMode) {
+ mContext = context;
+ mIsChecklistMode = isChecklistMode;
+
+ // 先默认隐藏复选框
+ mCheckBox.setVisibility(View.GONE);
mItemData = data;
-
+
+ // 重置视图状态
+ mTitle.setVisibility(View.VISIBLE);
+ mChecklistTitle.setVisibility(View.GONE);
+ mChecklistStatus.setVisibility(View.GONE);
+
// 处理通话记录文件夹
if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) {
mCallName.setVisibility(View.GONE);
@@ -93,7 +184,7 @@ public class NotesListItem extends LinearLayout {
mTitle.setText(context.getString(R.string.call_record_folder_name)
+ context.getString(R.string.format_folder_files_count, data.getNotesCount()));
mAlert.setImageResource(R.drawable.call_record);
- }
+ }
// 处理通话记录笔记
else if (data.getParentId() == Notes.ID_CALL_RECORD_FOLDER) {
mCallName.setVisibility(View.VISIBLE);
@@ -106,30 +197,114 @@ public class NotesListItem extends LinearLayout {
} else {
mAlert.setVisibility(View.GONE);
}
- }
+ }
// 处理普通文件夹或笔记
else {
mCallName.setVisibility(View.GONE);
- mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem);
if (data.getType() == Notes.TYPE_FOLDER) {
// 文件夹显示格式:名称 + 数量
+ mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem);
mTitle.setText(data.getSnippet()
+ context.getString(R.string.format_folder_files_count,
- data.getNotesCount()));
+ data.getNotesCount()));
mAlert.setVisibility(View.GONE);
} else {
- // 笔记显示格式:摘要
- mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet()));
- if (data.hasAlert()) {
- mAlert.setImageResource(R.drawable.clock);
- mAlert.setVisibility(View.VISIBLE);
+ // 处理清单模式
+ if (isChecklistMode) {
+ // 清单模式:显示编辑框和复选框,隐藏TextView和状态指示器
+ mTitle.setVisibility(View.GONE);
+ mChecklistTitle.setVisibility(View.VISIBLE);
+ mCheckBox.setVisibility(View.VISIBLE);
+ mChecklistStatus.setVisibility(View.GONE);
+
+ // 设置清单标题
+ String title = data.getSnippet();
+ mChecklistTitle.setText(title);
+ mChecklistTitle.setSelection(title.length());
+
+ // 初始状态下,EditText不可编辑,只能长按后编辑
+ mChecklistTitle.setFocusable(false);
+ mChecklistTitle.setFocusableInTouchMode(false);
+ mChecklistTitle.setClickable(false);
+ mChecklistTitle.setCursorVisible(false);
+
+ // 根据完成状态设置复选框和样式
+ boolean isChecked = data.isChecked();
+ mCheckBox.setChecked(isChecked);
+ updateChecklistStyle(isChecked);
+
+ // 添加复选框点击事件,切换完成状态
+ mCheckBox.setClickable(true);
+ mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ // 切换完成状态
+ data.setChecked(isChecked);
+
+ // 更新UI
+ updateChecklistStyle(isChecked);
+
+ // 通知监听器,保存完成状态到数据库
+ if (mOnCheckStatusChangedListener != null) {
+ mOnCheckStatusChangedListener.onCheckStatusChanged(data.getId(), isChecked);
+ }
+ }
+ });
+
+ // 添加长按事件,长按后可编辑
+ mChecklistTitle.setLongClickable(true);
+ mChecklistTitle.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ // 设置为可编辑状态
+ mChecklistTitle.setFocusable(true);
+ mChecklistTitle.setFocusableInTouchMode(true);
+ mChecklistTitle.setClickable(true);
+ mChecklistTitle.setCursorVisible(true);
+
+ // 获得焦点并弹出键盘
+ mChecklistTitle.requestFocus();
+ mChecklistTitle.setSelection(mChecklistTitle.getText().length());
+
+ // 强制弹出键盘
+ InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
+ if (imm != null) {
+ imm.showSoftInput(mChecklistTitle, InputMethodManager.SHOW_FORCED);
+ }
+
+ return true; // 消耗长按事件,避免触发其他长按事件
+ }
+ });
+
+ // 添加焦点变化监听器,失去焦点时保存修改并恢复为不可编辑状态
+ mChecklistTitle.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (!hasFocus) {
+ // 失去焦点时,保存修改并恢复为不可编辑状态
+ mChecklistTitle.setFocusable(false);
+ mChecklistTitle.setFocusableInTouchMode(false);
+ mChecklistTitle.setClickable(false);
+ mChecklistTitle.setCursorVisible(false);
+ }
+ }
+ });
} else {
- mAlert.setVisibility(View.GONE);
+ // 普通模式:显示TextView,隐藏编辑框
+ mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem);
+ mTitle.setText(DataUtils.getFormattedSnippet(data.getSnippet()));
+
+ if (data.hasAlert()) {
+ mAlert.setImageResource(R.drawable.clock);
+ mAlert.setVisibility(View.VISIBLE);
+ } else {
+ mAlert.setVisibility(View.GONE);
+ }
}
}
}
-
+
// 设置修改时间
mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate()));
@@ -137,15 +312,44 @@ public class NotesListItem extends LinearLayout {
setBackground(data);
}
+ /**
+ * 更新清单状态图标
+ */
+ private void updateChecklistStatus() {
+ if (mChecklistStatus == null || mItemData == null) {
+ return;
+ }
+
+ // TODO: 根据清单完成情况更新状态图标
+ // 这里可以实现逻辑,检查清单中已完成项的比例,显示不同的状态图标
+ mChecklistStatus.setImageResource(R.drawable.clock);
+ }
+
+ /**
+ * 更新清单项目样式
+ * @param isChecked 是否已完成
+ */
+ private void updateChecklistStyle(boolean isChecked) {
+ if (isChecked) {
+ // 已完成:显示删除线,文字变暗
+ mChecklistTitle.setPaintFlags(mChecklistTitle.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
+ mChecklistTitle.setTextColor(Color.GRAY);
+ } else {
+ // 未完成:正常显示
+ mChecklistTitle.setPaintFlags(mChecklistTitle.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
+ mChecklistTitle.setTextColor(Color.BLACK);
+ }
+ }
+
/**
* 设置笔记项的背景
* @param data 笔记项数据
*/
private void setBackground(NoteItemData data) {
int id = data.getBgColorId();
-
- if (data.getType() == Notes.TYPE_NOTE) {
- // 根据笔记在列表中的位置选择不同的背景
+
+ if (data.getType() == Notes.TYPE_NOTE || data.getType() == Notes.TYPE_CHECKLIST) {
+ // 根据笔记或清单在列表中的位置选择不同的背景
if (data.isSingle() || data.isOneFollowingFolder()) {
setBackgroundResource(NoteItemBgResources.getNoteBgSingleRes(id));
} else if (data.isLast()) {
diff --git a/src/Notes-master/test_build.sh b/src/Notes-master/test_build.sh
new file mode 100644
index 0000000..0a0cc98
--- /dev/null
+++ b/src/Notes-master/test_build.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+echo "Checking Android project structure..."
+
+# Check if this is an Android project
+if [ -f "AndroidManifest.xml" ]; then
+ echo "Found AndroidManifest.xml"
+else
+ echo "Error: No AndroidManifest.xml found"
+ exit 1
+fi
+
+# Check if src directory exists
+if [ -d "src" ]; then
+ echo "Found src directory"
+else
+ echo "Error: No src directory found"
+ exit 1
+fi
+
+# Check if res directory exists
+if [ -d "res" ]; then
+ echo "Found res directory"
+else
+ echo "Error: No res directory found"
+ exit 1
+fi
+
+echo "Project structure is valid!"
+echo "The project should be ready to build with Android SDK tools."
+echo "You can use the following command to build the project:"
+echo "android update project -p . && ant debug"