diff --git a/src/Notes-master/gradle script/.gradle/8.9/checksums/checksums.lock b/src/Notes-master/gradle script/.gradle/8.9/checksums/checksums.lock
deleted file mode 100644
index 46894bf..0000000
Binary files a/src/Notes-master/gradle script/.gradle/8.9/checksums/checksums.lock and /dev/null differ
diff --git a/src/Notes-master/gradle script/.gradle/8.9/dependencies-accessors/gc.properties b/src/Notes-master/gradle script/.gradle/8.9/dependencies-accessors/gc.properties
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Notes-master/gradle script/.gradle/8.9/executionHistory/executionHistory.lock b/src/Notes-master/gradle script/.gradle/8.9/executionHistory/executionHistory.lock
deleted file mode 100644
index 34dc97a..0000000
Binary files a/src/Notes-master/gradle script/.gradle/8.9/executionHistory/executionHistory.lock and /dev/null differ
diff --git a/src/Notes-master/gradle script/.gradle/8.9/fileChanges/last-build.bin b/src/Notes-master/gradle script/.gradle/8.9/fileChanges/last-build.bin
deleted file mode 100644
index f76dd23..0000000
Binary files a/src/Notes-master/gradle script/.gradle/8.9/fileChanges/last-build.bin and /dev/null differ
diff --git a/src/Notes-master/gradle script/.gradle/8.9/fileHashes/fileHashes.lock b/src/Notes-master/gradle script/.gradle/8.9/fileHashes/fileHashes.lock
deleted file mode 100644
index a15b41f..0000000
Binary files a/src/Notes-master/gradle script/.gradle/8.9/fileHashes/fileHashes.lock and /dev/null differ
diff --git a/src/Notes-master/gradle script/.gradle/8.9/gc.properties b/src/Notes-master/gradle script/.gradle/8.9/gc.properties
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Notes-master/gradle script/.gradle/9.2.0/checksums/checksums.lock b/src/Notes-master/gradle script/.gradle/9.2.0/checksums/checksums.lock
deleted file mode 100644
index 0480091..0000000
Binary files a/src/Notes-master/gradle script/.gradle/9.2.0/checksums/checksums.lock and /dev/null differ
diff --git a/src/Notes-master/gradle script/.gradle/9.2.0/fileChanges/last-build.bin b/src/Notes-master/gradle script/.gradle/9.2.0/fileChanges/last-build.bin
deleted file mode 100644
index f76dd23..0000000
Binary files a/src/Notes-master/gradle script/.gradle/9.2.0/fileChanges/last-build.bin and /dev/null differ
diff --git a/src/Notes-master/gradle script/.gradle/9.2.0/fileHashes/fileHashes.bin b/src/Notes-master/gradle script/.gradle/9.2.0/fileHashes/fileHashes.bin
deleted file mode 100644
index 42cfb00..0000000
Binary files a/src/Notes-master/gradle script/.gradle/9.2.0/fileHashes/fileHashes.bin and /dev/null differ
diff --git a/src/Notes-master/gradle script/.gradle/9.2.0/fileHashes/fileHashes.lock b/src/Notes-master/gradle script/.gradle/9.2.0/fileHashes/fileHashes.lock
deleted file mode 100644
index f4b0cf6..0000000
Binary files a/src/Notes-master/gradle script/.gradle/9.2.0/fileHashes/fileHashes.lock and /dev/null differ
diff --git a/src/Notes-master/gradle script/.gradle/9.2.0/gc.properties b/src/Notes-master/gradle script/.gradle/9.2.0/gc.properties
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Notes-master/gradle script/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/src/Notes-master/gradle script/.gradle/buildOutputCleanup/buildOutputCleanup.lock
deleted file mode 100644
index 04a527e..0000000
Binary files a/src/Notes-master/gradle script/.gradle/buildOutputCleanup/buildOutputCleanup.lock and /dev/null differ
diff --git a/src/Notes-master/gradle script/.gradle/buildOutputCleanup/cache.properties b/src/Notes-master/gradle script/.gradle/buildOutputCleanup/cache.properties
deleted file mode 100644
index 1ade9e1..0000000
--- a/src/Notes-master/gradle script/.gradle/buildOutputCleanup/cache.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-#Wed Jan 28 09:46:21 CST 2026
-gradle.version=9.2.0
diff --git a/src/Notes-master/gradle script/.gradle/vcs-1/gc.properties b/src/Notes-master/gradle script/.gradle/vcs-1/gc.properties
deleted file mode 100644
index e69de29..0000000
diff --git a/src/Notes-master/gradle script/build/reports/problems/problems-report.html b/src/Notes-master/gradle script/build/reports/problems/problems-report.html
deleted file mode 100644
index 381ccca..0000000
--- a/src/Notes-master/gradle script/build/reports/problems/problems-report.html
+++ /dev/null
@@ -1,659 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- Gradle Configuration Cache
-
-
-
-
-
-
- Loading...
-
-
-
-
-
-
-
diff --git a/src/Notes-master/res/drawable/drawable-hdpi/bg_btn_insert_photo.png b/src/Notes-master/res/drawable/drawable-hdpi/bg_btn_insert_photo.png
new file mode 100644
index 0000000..f8a0bfb
Binary files /dev/null and b/src/Notes-master/res/drawable/drawable-hdpi/bg_btn_insert_photo.png differ
diff --git a/src/Notes-master/res/drawable/drawable-hdpi/bg_btn_voice_transfomer.png b/src/Notes-master/res/drawable/drawable-hdpi/bg_btn_voice_transfomer.png
new file mode 100644
index 0000000..632a08e
Binary files /dev/null and b/src/Notes-master/res/drawable/drawable-hdpi/bg_btn_voice_transfomer.png differ
diff --git a/src/Notes-master/src/net/micode/notes/tool/ResourceParser.java b/src/Notes-master/src/net/micode/notes/tool/ResourceParser.java
index 14bae33..72d9b47 100644
--- a/src/Notes-master/src/net/micode/notes/tool/ResourceParser.java
+++ b/src/Notes-master/src/net/micode/notes/tool/ResourceParser.java
@@ -118,6 +118,9 @@ public class ResourceParser {
* @return 背景资源ID
*/
public static int getNoteBgResource(int id) {
+ if (id < 0 || id >= BG_EDIT_RESOURCES.length) {
+ return BG_EDIT_RESOURCES[BG_DEFAULT_COLOR];
+ }
return BG_EDIT_RESOURCES[id];
}
@@ -127,6 +130,9 @@ public class ResourceParser {
* @return 标题栏背景资源ID
*/
public static int getNoteTitleBgResource(int id) {
+ if (id < 0 || id >= BG_EDIT_TITLE_RESOURCES.length) {
+ return BG_EDIT_TITLE_RESOURCES[BG_DEFAULT_COLOR];
+ }
return BG_EDIT_TITLE_RESOURCES[id];
}
}
@@ -205,6 +211,9 @@ public class ResourceParser {
* @return 首项背景资源ID
*/
public static int getNoteBgFirstRes(int id) {
+ if (id < 0 || id >= BG_FIRST_RESOURCES.length) {
+ return BG_FIRST_RESOURCES[BG_DEFAULT_COLOR];
+ }
return BG_FIRST_RESOURCES[id];
}
@@ -214,6 +223,9 @@ public class ResourceParser {
* @return 末项背景资源ID
*/
public static int getNoteBgLastRes(int id) {
+ if (id < 0 || id >= BG_LAST_RESOURCES.length) {
+ return BG_LAST_RESOURCES[BG_DEFAULT_COLOR];
+ }
return BG_LAST_RESOURCES[id];
}
@@ -223,6 +235,9 @@ public class ResourceParser {
* @return 单项背景资源ID
*/
public static int getNoteBgSingleRes(int id) {
+ if (id < 0 || id >= BG_SINGLE_RESOURCES.length) {
+ return BG_SINGLE_RESOURCES[BG_DEFAULT_COLOR];
+ }
return BG_SINGLE_RESOURCES[id];
}
@@ -232,6 +247,9 @@ public class ResourceParser {
* @return 中间项背景资源ID
*/
public static int getNoteBgNormalRes(int id) {
+ if (id < 0 || id >= BG_NORMAL_RESOURCES.length) {
+ return BG_NORMAL_RESOURCES[BG_DEFAULT_COLOR];
+ }
return BG_NORMAL_RESOURCES[id];
}
@@ -267,6 +285,9 @@ public class ResourceParser {
* @return 2x小部件背景资源ID
*/
public static int getWidget2xBgResource(int id) {
+ if (id < 0 || id >= BG_2X_RESOURCES.length) {
+ return BG_2X_RESOURCES[BG_DEFAULT_COLOR];
+ }
return BG_2X_RESOURCES[id];
}
@@ -288,6 +309,9 @@ public class ResourceParser {
* @return 4x小部件背景资源ID
*/
public static int getWidget4xBgResource(int id) {
+ if (id < 0 || id >= BG_4X_RESOURCES.length) {
+ return BG_4X_RESOURCES[BG_DEFAULT_COLOR];
+ }
return BG_4X_RESOURCES[id];
}
}
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 a56fa24..39b0da4 100644
--- a/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
+++ b/src/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java
@@ -234,6 +234,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private EditText mTagInput; // 标签输入框
private Button mAddTagButton; // 添加标签按钮
private ArrayList mTagsList; // 标签列表
+
+ // 视图缓存,减少对象创建
+ private ArrayList mViewCache = new ArrayList<>();
+ private static final int MAX_CACHE_SIZE = 10; // 最大缓存大小
+
+ // 延迟保存相关
+ private android.os.Handler mSaveNoteHandler = new android.os.Handler();
+ private TextView mSaveHint; // 保存成功提示视图
// 搜索历史相关
private static final String PREFERENCE_SEARCH_HISTORY = "search_history"; // 搜索历史偏好设置键
@@ -1337,58 +1345,114 @@ public class NoteEditActivity extends Activity implements OnClickListener,
long startTime = System.currentTimeMillis();
Log.d(TAG, "switchToListMode started, text length: " + (text != null ? text.length() : 0));
- // 处理null文本,避免空指针异常(OMO)
+ // 处理null文本,避免空指针异常
final String processedText = text != null ? text : "";
- // 预处理:在后台线程中分割文本和准备数据
- new Thread(new Runnable() {
- @Override
- public void run() {
- final String[] items = processedText.split("\n"); // 按行分割文本
- Log.d(TAG, "switchToListMode: split into " + items.length + " items");
-
- // 切换回主线程更新UI
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- // 批量创建和添加视图,减少布局重绘
- mEditTextList.removeAllViews(); // 清空编辑文本列表
-
- int index = 0;
- View lastItem = null;
-
- // 先创建所有视图
- ArrayList viewsToAdd = new ArrayList<>();
- for (String item : items) {
- if(!TextUtils.isEmpty(item)) {
- View listItem = getListItem(item, index);
- viewsToAdd.add(listItem);
- index++;
- }
- }
-
- // 添加最后一个空列表项
- lastItem = getListItem("", index);
- viewsToAdd.add(lastItem);
-
- // 一次性添加所有视图到容器
- for (View view : viewsToAdd) {
- mEditTextList.addView(view);
+ // 优化:直接在主线程处理,减少线程切换开销
+ // 对于大多数情况,文本分割和视图创建的开销很小
+ // 只有在文本特别长时才需要考虑后台线程
+ if (processedText.length() > 10000) {
+ // 对于长文本,使用后台线程
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ final String[] items = processTextForListMode(processedText);
+ Log.d(TAG, "switchToListMode: split into " + items.length + " items");
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ createListModeViews(items);
+ long endTime = System.currentTimeMillis();
+ Log.d(TAG, "switchToListMode completed in " + (endTime - startTime) + "ms");
}
+ });
+ }
+ }).start();
+ } else {
+ // 对于短文本,直接在主线程处理
+ final String[] items = processTextForListMode(processedText);
+ Log.d(TAG, "switchToListMode: split into " + items.length + " items");
+ createListModeViews(items);
+ long endTime = System.currentTimeMillis();
+ Log.d(TAG, "switchToListMode completed in " + (endTime - startTime) + "ms");
+ }
+ }
- // 设置焦点
- ListItemViewHolder holder = (ListItemViewHolder) lastItem.getTag();
- holder.etEditText.requestFocus();
+ /**
+ * 处理文本,为清单模式做准备
+ * @param text 原始文本
+ * @return 处理后的文本数组
+ */
+ private String[] processTextForListMode(String text) {
+ // 移除HTML标签,只保留纯文本
+ String plainText = removeHtmlTags(text);
+ // 按行分割
+ return plainText.split("\n");
+ }
- mNoteEditor.setVisibility(View.GONE); // 隐藏普通编辑器
- mEditTextList.setVisibility(View.VISIBLE); // 显示清单编辑器
+ /**
+ * 移除HTML标签,只保留纯文本
+ * @param html HTML文本
+ * @return 纯文本
+ */
+ private String removeHtmlTags(String html) {
+ // 简单的HTML标签移除,适合大多数情况
+ if (TextUtils.isEmpty(html)) {
+ return "";
+ }
+ // 移除常见HTML标签
+ String plainText = html.replaceAll("<[^>]+>", "");
+ // 处理HTML实体
+ plainText = plainText.replaceAll(" ", " ");
+ plainText = plainText.replaceAll("<", "<");
+ plainText = plainText.replaceAll(">", ">");
+ plainText = plainText.replaceAll("&", "&");
+ return plainText;
+ }
- long endTime = System.currentTimeMillis();
- Log.d(TAG, "switchToListMode completed in " + (endTime - startTime) + "ms");
- }
- });
+ /**
+ * 创建清单模式的视图
+ * @param items 文本项数组
+ */
+ private void createListModeViews(String[] items) {
+ // 回收现有视图到缓存,减少内存占用
+ int childCount = mEditTextList.getChildCount();
+ for (int i = childCount - 1; i >= 0; i--) {
+ View view = mEditTextList.getChildAt(i);
+ recycleView(view);
+ }
+ // 清空编辑文本列表
+ mEditTextList.removeAllViews();
+
+ // 批量创建视图
+ ArrayList viewsToAdd = new ArrayList<>();
+ int index = 0;
+
+ for (String item : items) {
+ if (!TextUtils.isEmpty(item)) {
+ View listItem = getListItem(item, index);
+ viewsToAdd.add(listItem);
+ index++;
}
- }).start();
+ }
+
+ // 添加最后一个空列表项
+ View lastItem = getListItem("", index);
+ viewsToAdd.add(lastItem);
+
+ // 批量添加视图,减少布局重绘
+ for (View view : viewsToAdd) {
+ mEditTextList.addView(view);
+ }
+
+ // 设置焦点
+ ListItemViewHolder holder = (ListItemViewHolder) lastItem.getTag();
+ holder.etEditText.requestFocus();
+
+ // 显示/隐藏编辑器
+ mNoteEditor.setVisibility(View.GONE);
+ mEditTextList.setVisibility(View.VISIBLE);
}
/**
@@ -1446,13 +1510,22 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* @return 列表项视图
*/
private View getListItem(String item, int index) {
- View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
+ // 优先从缓存中获取视图,减少布局inflate开销
+ View view = null;
+ if (!mViewCache.isEmpty()) {
+ view = mViewCache.remove(0);
+ } else {
+ view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
+ }
// 创建并缓存ViewHolder
- ListItemViewHolder holder = new ListItemViewHolder();
- holder.etEditText = (NoteEditText) view.findViewById(R.id.et_edit_text);
- holder.cbEditItem = (CheckBox) view.findViewById(R.id.cb_edit_item);
- view.setTag(holder);
+ ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
+ if (holder == null) {
+ holder = new ListItemViewHolder();
+ holder.etEditText = (NoteEditText) view.findViewById(R.id.et_edit_text);
+ holder.cbEditItem = (CheckBox) view.findViewById(R.id.cb_edit_item);
+ view.setTag(holder);
+ }
final NoteEditText edit = holder.etEditText;
edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
@@ -1462,10 +1535,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
+ // 添加删除线和灰色效果
edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
+ edit.setTextColor(Color.GRAY);
+ // 将已完成项目移到列表底部
+ moveCompletedItemToBottom(edit);
} else {
+ // 移除删除线和恢复颜色
edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
+ edit.setTextColor(Color.BLACK);
+ // 将未完成项目移到列表顶部
+ moveUncompletedItemToTop(edit);
}
+ // 延迟保存,避免频繁操作导致卡顿
+ saveNoteDelayed();
}
});
@@ -1473,13 +1556,120 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if (item.startsWith(TAG_CHECKED)) {
cb.setChecked(true);
edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
+ edit.setTextColor(Color.GRAY);
item = item.substring(TAG_CHECKED.length(), item.length()).trim();
} else if (item.startsWith(TAG_UNCHECKED)) {
cb.setChecked(false);
edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
+ edit.setTextColor(Color.BLACK);
item = item.substring(TAG_UNCHECKED.length(), item.length()).trim();
+ } else {
+ // 重置为默认状态
+ cb.setChecked(false);
+ edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
+ edit.setTextColor(Color.BLACK);
}
+ // 设置列表项点击事件监听器,用于标记项目为已完成状态
+ view.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // 添加点击反馈效果
+ v.setBackgroundColor(Color.parseColor("#E0E0E0"));
+ v.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ v.setBackgroundColor(Color.TRANSPARENT);
+ }
+ }, 100);
+
+ // 处理列表项点击事件,标记项目为已完成状态
+ CheckBox checkBox = (CheckBox) v.findViewById(R.id.cb_edit_item);
+ checkBox.setChecked(!checkBox.isChecked());
+ }
+ });
+
+ // 设置复选框点击事件监听器
+ cb.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // 直接切换选中状态,避免与列表项点击事件冲突
+ cb.setChecked(!cb.isChecked());
+ }
+ });
+
+ // 设置编辑文本点击事件监听器,用于进入详细编辑模式
+ edit.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ // 阻止事件冒泡,避免触发列表项的点击事件
+ v.setClickable(true);
+ v.setFocusable(true);
+ v.setFocusableInTouchMode(true);
+
+ // 添加点击反馈效果
+ edit.setBackgroundColor(Color.parseColor("#F0F0F0"));
+ edit.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ edit.setBackgroundColor(Color.TRANSPARENT);
+ }
+ }, 100);
+
+ // 处理编辑文本点击事件,进入详细编辑模式
+ edit.requestFocus();
+ edit.setSelection(edit.length());
+ // 显示软键盘
+ getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+ }
+ });
+
+ // 为编辑文本添加文本变化监听器,确保修改能够被保存
+ edit.addTextChangedListener(new android.text.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(android.text.Editable s) {
+ // 文本变化后延迟保存笔记,避免频繁操作导致卡顿
+ saveNoteDelayed();
+ }
+ });
+
+ // 设置列表项长按事件监听器
+ edit.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ try {
+ // 添加长按反馈效果
+ edit.setBackgroundColor(Color.parseColor("#D0D0D0"));
+ edit.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ edit.setBackgroundColor(Color.TRANSPARENT);
+ }
+ }, 100);
+
+ // 处理长按事件,将清单标记为已完成状态
+ View parentView = (View) v.getParent();
+ if (parentView != null) {
+ CheckBox checkBox = (CheckBox) parentView.findViewById(R.id.cb_edit_item);
+ if (checkBox != null) {
+ checkBox.setChecked(!checkBox.isChecked());
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error in long click listener: " + e.getMessage());
+ }
+ return true;
+ }
+ });
+
edit.setOnTextViewChangeListener(this);
edit.setIndex(index);
edit.setText(getHighlightQueryResult(item, mUserQuery));
@@ -1508,6 +1698,161 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
+ /**
+ * 将已完成的项目移到列表底部
+ * @param edit 编辑文本框
+ */
+ private void moveCompletedItemToBottom(NoteEditText edit) {
+ try {
+ int childCount = mEditTextList.getChildCount();
+ if (childCount <= 1 || edit == null) {
+ return;
+ }
+
+ // 找到当前项目的索引
+ int currentIndex = -1;
+ for (int i = 0; i < childCount; i++) {
+ View view = mEditTextList.getChildAt(i);
+ if (view != null) {
+ ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
+ if (holder != null && holder.etEditText == edit) {
+ currentIndex = i;
+ break;
+ }
+ }
+ }
+
+ if (currentIndex == -1 || currentIndex == childCount - 1) {
+ return;
+ }
+
+ // 找到第一个未完成的项目索引
+ int firstUncompletedIndex = -1;
+ for (int i = currentIndex + 1; i < childCount; i++) {
+ View view = mEditTextList.getChildAt(i);
+ if (view != null) {
+ ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
+ if (holder != null && holder.cbEditItem != null && !holder.cbEditItem.isChecked()) {
+ firstUncompletedIndex = i;
+ break;
+ }
+ }
+ }
+
+ if (firstUncompletedIndex != -1) {
+ // 保存当前项目
+ View currentView = mEditTextList.getChildAt(currentIndex);
+ if (currentView != null) {
+ mEditTextList.removeViewAt(currentIndex);
+ // 插入到第一个未完成项目之前
+ mEditTextList.addView(currentView, firstUncompletedIndex - 1);
+ // 更新索引
+ updateItemIndices();
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error in moveCompletedItemToBottom: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 将未完成的项目移到列表顶部
+ * @param edit 编辑文本框
+ */
+ private void moveUncompletedItemToTop(NoteEditText edit) {
+ try {
+ int childCount = mEditTextList.getChildCount();
+ if (childCount <= 1 || edit == null) {
+ return;
+ }
+
+ // 找到当前项目的索引
+ int currentIndex = -1;
+ for (int i = 0; i < childCount; i++) {
+ View view = mEditTextList.getChildAt(i);
+ if (view != null) {
+ ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
+ if (holder != null && holder.etEditText == edit) {
+ currentIndex = i;
+ break;
+ }
+ }
+ }
+
+ if (currentIndex == -1 || currentIndex == 0) {
+ return;
+ }
+
+ // 找到最后一个已完成的项目索引
+ int lastCompletedIndex = -1;
+ for (int i = 0; i < currentIndex; i++) {
+ View view = mEditTextList.getChildAt(i);
+ if (view != null) {
+ ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
+ if (holder != null && holder.cbEditItem != null && holder.cbEditItem.isChecked()) {
+ lastCompletedIndex = i;
+ }
+ }
+ }
+
+ // 保存当前项目
+ View currentView = mEditTextList.getChildAt(currentIndex);
+ if (currentView != null) {
+ mEditTextList.removeViewAt(currentIndex);
+ // 插入到最后一个已完成项目之后
+ mEditTextList.addView(currentView, lastCompletedIndex + 1);
+ // 更新索引
+ updateItemIndices();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error in moveUncompletedItemToTop: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 更新所有项目的索引
+ */
+ private void updateItemIndices() {
+ try {
+ int childCount = mEditTextList.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View view = mEditTextList.getChildAt(i);
+ if (view != null) {
+ ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
+ if (holder != null && holder.etEditText != null) {
+ holder.etEditText.setIndex(i);
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error in updateItemIndices: " + e.getMessage());
+ }
+ }
+
+ /**
+ * 回收视图到缓存
+ * @param view 要回收的视图
+ */
+ private void recycleView(View view) {
+ if (view != null && mViewCache.size() < MAX_CACHE_SIZE) {
+ // 清除视图的内容和监听器,避免内存泄漏
+ ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
+ if (holder != null) {
+ holder.etEditText.setText("");
+ holder.etEditText.setOnTextViewChangeListener(null);
+ holder.cbEditItem.setOnCheckedChangeListener(null);
+ }
+ mViewCache.add(view);
+ }
+ }
+
+ /**
+ * 清空视图缓存
+ */
+ private void clearViewCache() {
+ mViewCache.clear();
+ }
+
/**
* 清单模式改变时调用
* 实现NoteSettingChangedListener接口
@@ -1580,26 +1925,35 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private boolean getWorkingText() {
boolean hasChecked = false;
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
- StringBuilder sb = new StringBuilder();
+ // 优化:使用StringBuilder的初始容量,减少扩容开销
+ StringBuilder sb = new StringBuilder(mEditTextList.getChildCount() * 50); // 预估每个项目平均50字符
for (int i = 0; i < mEditTextList.getChildCount(); i++) {
View view = mEditTextList.getChildAt(i);
- ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
- NoteEditText edit = holder.etEditText;
- if (!TextUtils.isEmpty(edit.getText())) {
- if (holder.cbEditItem.isChecked()) {
- sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n");
- hasChecked = true;
- } else {
- sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n");
+ if (view != null) {
+ ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
+ if (holder != null && holder.etEditText != null && holder.cbEditItem != null) {
+ NoteEditText edit = holder.etEditText;
+ if (!TextUtils.isEmpty(edit.getText())) {
+ if (holder.cbEditItem.isChecked()) {
+ sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n");
+ hasChecked = true;
+ } else {
+ sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n");
+ }
+ }
}
}
}
mWorkingNote.setWorkingText(sb.toString());
} else {
// 对于富文本模式,保存当前的HTML内容,包括Base64图片
- String currentHtml = mNoteEditor.getHtml();
- Log.d(TAG, "getWorkingText called for rich text mode, saving HTML content: " + currentHtml);
- mWorkingNote.setWorkingText(currentHtml);
+ // 优化:避免不必要的日志输出,减少IO开销
+ if (mNoteEditor != null) {
+ String currentHtml = mNoteEditor.getHtml();
+ if (currentHtml != null) {
+ mWorkingNote.setWorkingText(currentHtml);
+ }
+ }
}
return hasChecked;
}
@@ -1848,6 +2202,71 @@ public class NoteEditActivity extends Activity implements OnClickListener,
Toast.makeText(this, resId, duration).show();
}
+ /**
+ * 延迟保存笔记,避免频繁操作导致卡顿
+ */
+ private void saveNoteDelayed() {
+ // 移除之前的延迟保存任务
+ if (mSaveNoteHandler != null) {
+ mSaveNoteHandler.removeCallbacksAndMessages(null);
+ }
+ // 延迟500毫秒保存,避免频繁操作导致卡顿
+ mSaveNoteHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (saveNote()) {
+ // 保存成功的简短提示
+ showSaveSuccessHint();
+ }
+ }
+ }, 500);
+ }
+
+ /**
+ * 显示保存成功的简短提示
+ */
+ private void showSaveSuccessHint() {
+ if (mSaveHint == null) {
+ mSaveHint = new TextView(this);
+ mSaveHint.setText("已保存");
+ mSaveHint.setTextColor(Color.GRAY);
+ mSaveHint.setTextSize(12);
+ mSaveHint.setPadding(10, 5, 10, 5);
+ mSaveHint.setGravity(Gravity.CENTER);
+ mSaveHint.setBackgroundColor(Color.parseColor("#E0E0E0"));
+ mSaveHint.setAlpha(0.0f);
+
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ );
+ params.gravity = Gravity.CENTER;
+ params.topMargin = 10;
+ mEditTextList.addView(mSaveHint, params);
+ }
+
+ // 显示动画
+ mSaveHint.animate()
+ .alpha(1.0f)
+ .setDuration(300)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ // 延迟后隐藏
+ mSaveHint.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mSaveHint.animate()
+ .alpha(0.0f)
+ .setDuration(300)
+ .start();
+ }
+ }, 1000);
+ }
+ })
+ .start();
+ }
+
/**
* 从相册选择图片 OMO
*/