|
|
|
|
@ -130,6 +130,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
public ImageView ibSetBgColor; // 设置背景颜色按钮
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 清单列表项视图持有者类
|
|
|
|
|
* 用于缓存清单列表项视图的控件引用,提高性能
|
|
|
|
|
*/
|
|
|
|
|
private class ListItemViewHolder {
|
|
|
|
|
public CheckBox cbEditItem; // 清单项复选框
|
|
|
|
|
public NoteEditText etEditText; // 清单项编辑文本
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 背景选择器按钮映射
|
|
|
|
|
* 用于将背景选择按钮ID映射到对应的背景颜色常量
|
|
|
|
|
@ -1277,25 +1286,61 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
* @param text 要转换的文本内容
|
|
|
|
|
*/
|
|
|
|
|
private void switchToListMode(String text) {
|
|
|
|
|
long startTime = System.currentTimeMillis();
|
|
|
|
|
Log.d(TAG, "switchToListMode started, text length: " + (text != null ? text.length() : 0));
|
|
|
|
|
|
|
|
|
|
// 处理null文本,避免空指针异常(OMO)
|
|
|
|
|
if (text == null) {
|
|
|
|
|
text = "";
|
|
|
|
|
}
|
|
|
|
|
final String processedText = text != null ? text : "";
|
|
|
|
|
|
|
|
|
|
mEditTextList.removeAllViews(); // 清空编辑文本列表
|
|
|
|
|
String[] items = text.split("\n"); // 按行分割文本
|
|
|
|
|
int index = 0;
|
|
|
|
|
for (String item : items) {
|
|
|
|
|
if(!TextUtils.isEmpty(item)) {
|
|
|
|
|
mEditTextList.addView(getListItem(item, index)); // 添加列表项
|
|
|
|
|
index++;
|
|
|
|
|
// 预处理:在后台线程中分割文本和准备数据
|
|
|
|
|
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<View> 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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置焦点
|
|
|
|
|
ListItemViewHolder holder = (ListItemViewHolder) lastItem.getTag();
|
|
|
|
|
holder.etEditText.requestFocus();
|
|
|
|
|
|
|
|
|
|
mNoteEditor.setVisibility(View.GONE); // 隐藏普通编辑器
|
|
|
|
|
mEditTextList.setVisibility(View.VISIBLE); // 显示清单编辑器
|
|
|
|
|
|
|
|
|
|
long endTime = System.currentTimeMillis();
|
|
|
|
|
Log.d(TAG, "switchToListMode completed in " + (endTime - startTime) + "ms");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mEditTextList.addView(getListItem("", index)); // 添加最后一个空列表项
|
|
|
|
|
mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus(); // 设置焦点
|
|
|
|
|
|
|
|
|
|
mNoteEditor.setVisibility(View.GONE); // 隐藏普通编辑器
|
|
|
|
|
mEditTextList.setVisibility(View.VISIBLE); // 显示清单编辑器
|
|
|
|
|
}).start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -1306,24 +1351,42 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
* @return 带有高亮效果的文本
|
|
|
|
|
*/
|
|
|
|
|
private Spannable getHighlightQueryResult(String fullText, String userQuery) {
|
|
|
|
|
long startTime = System.currentTimeMillis();
|
|
|
|
|
|
|
|
|
|
String text = fullText == null ? "" : fullText;
|
|
|
|
|
SpannableString spannable = new SpannableString(text);
|
|
|
|
|
|
|
|
|
|
// 处理查询关键词高亮
|
|
|
|
|
if (!TextUtils.isEmpty(userQuery)) {
|
|
|
|
|
mPattern = Pattern.compile(userQuery); // 编译正则表达式
|
|
|
|
|
Matcher m = mPattern.matcher(text); // 创建匹配器
|
|
|
|
|
int start = 0;
|
|
|
|
|
while (m.find(start)) {
|
|
|
|
|
// 设置高亮背景色
|
|
|
|
|
spannable.setSpan(
|
|
|
|
|
new BackgroundColorSpan(this.getResources().getColor(
|
|
|
|
|
R.color.user_query_highlight)), m.start(), m.end(),
|
|
|
|
|
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
|
|
|
|
start = m.end();
|
|
|
|
|
if (!TextUtils.isEmpty(userQuery) && !TextUtils.isEmpty(text)) {
|
|
|
|
|
try {
|
|
|
|
|
mPattern = Pattern.compile(userQuery); // 编译正则表达式
|
|
|
|
|
Matcher m = mPattern.matcher(text); // 创建匹配器
|
|
|
|
|
int start = 0;
|
|
|
|
|
int matchCount = 0;
|
|
|
|
|
while (m.find(start)) {
|
|
|
|
|
// 设置高亮背景色
|
|
|
|
|
spannable.setSpan(
|
|
|
|
|
new BackgroundColorSpan(this.getResources().getColor(
|
|
|
|
|
R.color.user_query_highlight)), m.start(), m.end(),
|
|
|
|
|
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
|
|
|
|
start = m.end();
|
|
|
|
|
matchCount++;
|
|
|
|
|
|
|
|
|
|
// 限制匹配数量,避免处理过多匹配项导致性能问题
|
|
|
|
|
if (matchCount > 100) {
|
|
|
|
|
Log.w(TAG, "getHighlightQueryResult: too many matches, stopping at 100");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Log.d(TAG, "getHighlightQueryResult: found " + matchCount + " matches");
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
Log.e(TAG, "Error in getHighlightQueryResult: " + e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long endTime = System.currentTimeMillis();
|
|
|
|
|
Log.d(TAG, "getHighlightQueryResult completed in " + (endTime - startTime) + "ms");
|
|
|
|
|
|
|
|
|
|
return spannable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1336,11 +1399,18 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
*/
|
|
|
|
|
private View getListItem(String item, int index) {
|
|
|
|
|
View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
|
|
|
|
|
final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
|
|
|
|
|
|
|
|
|
|
// 创建并缓存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);
|
|
|
|
|
|
|
|
|
|
final NoteEditText edit = holder.etEditText;
|
|
|
|
|
edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
|
|
|
|
|
|
|
|
|
|
// 设置复选框的选中状态变化监听器
|
|
|
|
|
CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item));
|
|
|
|
|
CheckBox cb = holder.cbEditItem;
|
|
|
|
|
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
|
if (isChecked) {
|
|
|
|
|
@ -1379,10 +1449,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
Log.e(TAG, "Wrong index, should not happen");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
View view = mEditTextList.getChildAt(index);
|
|
|
|
|
ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
|
|
|
|
|
|
|
|
|
|
if(hasText) {
|
|
|
|
|
mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE);
|
|
|
|
|
holder.cbEditItem.setVisibility(View.VISIBLE);
|
|
|
|
|
} else {
|
|
|
|
|
mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE);
|
|
|
|
|
holder.cbEditItem.setVisibility(View.GONE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -1461,9 +1535,10 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
for (int i = 0; i < mEditTextList.getChildCount(); i++) {
|
|
|
|
|
View view = mEditTextList.getChildAt(i);
|
|
|
|
|
NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
|
|
|
|
|
ListItemViewHolder holder = (ListItemViewHolder) view.getTag();
|
|
|
|
|
NoteEditText edit = holder.etEditText;
|
|
|
|
|
if (!TextUtils.isEmpty(edit.getText())) {
|
|
|
|
|
if (((CheckBox) view.findViewById(R.id.cb_edit_item)).isChecked()) {
|
|
|
|
|
if (holder.cbEditItem.isChecked()) {
|
|
|
|
|
sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n");
|
|
|
|
|
hasChecked = true;
|
|
|
|
|
} else {
|
|
|
|
|
|