From bc473aac618bfeef105d4dd087d0ec0371eb5a5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E4=BD=B3=E8=B1=AA?= <230340130@cauc.edu.cn> Date: Sun, 30 Mar 2025 19:18:04 +0800 Subject: [PATCH] =?UTF-8?q?v0.0=20-=E5=8E=9F=E5=A7=8B=E7=89=88=E6=9C=AC?= =?UTF-8?q?=EF=BC=8C=E4=B8=BA=E4=BA=86=E6=AD=A3=E5=B8=B8=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E5=AF=B9=E4=BA=8E=E4=B8=80=E4=BA=9B=E6=96=B9=E6=B3=95=E5=81=9A?= =?UTF-8?q?=E4=BA=86=E6=B3=A8=E9=87=8A=E5=8C=96=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/vcs.xml | 6 ++ app/src/main/AndroidManifest.xml | 46 ++++++-- .../net/micode/notes/ui/NoteEditActivity.java | 2 +- .../net/micode/notes/ui/NoteEditText.java | 100 +++++++++++++++++- app/src/main/res/values/styles.xml | 3 +- desktop.ini | 6 ++ 回收站 - 快捷方式.lnk | Bin 0 -> 327 bytes 7 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 .idea/vcs.xml create mode 100644 desktop.ini create mode 100644 回收站 - 快捷方式.lnk diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e061ed5..5574e2a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,8 +1,12 @@ + + + @@ -16,17 +20,17 @@ android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" - android:icon="@mipmap/ic_launcher" + android:icon="@drawable/icon_app" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Notesmaster" tools:targetApi="31"> + + - + + android:name="net.micode.notes.data.NotesProvider" + android:authorities="micode_notes" + android:multiprocess="true" + android:exported="false" + android:readPermission="com.example.notesmaster.permission.READ_NOTES" + android:writePermission="com.example.notesmaster.permission.WRITE_NOTES" /> + + + @@ -113,18 +124,20 @@ + + + + + @@ -149,7 +164,22 @@ - + + diff --git a/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java b/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java index 96a9ff8..a674d7a 100644 --- a/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java +++ b/app/src/main/java/net/micode/notes/ui/NoteEditActivity.java @@ -430,7 +430,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, if (id == R.id.btn_set_bg_color) { mNoteBgColorSelector.setVisibility(View.VISIBLE); findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( - - View.VISIBLE); + View.VISIBLE); } else if (sBgSelectorBtnsMap.containsKey(id)) { findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( View.GONE); diff --git a/app/src/main/java/net/micode/notes/ui/NoteEditText.java b/app/src/main/java/net/micode/notes/ui/NoteEditText.java index 2afe2a8..b4c2fc5 100644 --- a/app/src/main/java/net/micode/notes/ui/NoteEditText.java +++ b/app/src/main/java/net/micode/notes/ui/NoteEditText.java @@ -82,136 +82,232 @@ public class NoteEditText extends EditText { mIndex = 0; } + /** + * 设置索引值 + * 该方法用于从外部更新对象的索引状态 + * + * @param index 新的索引值,用于替换当前对象的索引 + */ public void setIndex(int index) { mIndex = index; } + /** + * 设置文本视图变化监听器 + * 用于在文本视图的内容发生变化时通知监听器 + * + * @param listener 实现了OnTextViewChangeListener接口的监听器实例 + */ public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { mOnTextViewChangeListener = listener; } + /** + * 构造函数,用于在 XML 布局中实例化 NoteEditText 组件。 + * + * @param context 上下文对象,包含应用环境信息 + * @param attrs 从 XML 布局文件中解析的属性集合 + */ public NoteEditText(Context context, AttributeSet attrs) { super(context, attrs, android.R.attr.editTextStyle); } + /** + * 构造函数,用于在 XML 布局中实例化 NoteEditText 组件,并允许指定默认样式。 + * + * @param context 上下文对象,包含应用环境信息 + * @param attrs 从 XML 布局文件中解析的属性集合 + * @param defStyle 默认样式资源 ID,用于自定义组件外观 + */ public NoteEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } + /** + * 处理触摸事件以实现特定的交互逻辑 + * 当用户触摸屏幕时,此方法被调用,用于处理触摸事件 + * 特别地,当触摸动作为按下时,它会计算触摸位置,并更新文本选择 + * + * @param event 触摸事件,包含触摸动作、位置等信息 + * @return 返回true表示事件已被处理,false表示未处理 + */ @Override public boolean onTouchEvent(MotionEvent event) { + // 根据触摸事件的类型进行不同的处理 switch (event.getAction()) { case MotionEvent.ACTION_DOWN: - + // 获取触摸点相对于视图的坐标 int x = (int) event.getX(); int y = (int) event.getY(); + // 调整坐标以考虑视图的内边距 x -= getTotalPaddingLeft(); y -= getTotalPaddingTop(); + // 调整坐标以考虑视图的滚动偏移 x += getScrollX(); y += getScrollY(); + // 获取视图中的文本布局 Layout layout = getLayout(); + // 根据垂直位置计算触摸点所在的文本行 int line = layout.getLineForVertical(y); + // 根据水平位置计算触摸点所在的文本偏移量 int off = layout.getOffsetForHorizontal(line, x); + // 更新文本选择 Selection.setSelection(getText(), off); break; } + // 调用父类的onTouchEvent方法以处理其他触摸事件 return super.onTouchEvent(event); } + /** + * 重写onKeyDown方法以处理特定的键盘事件 + * + * @param keyCode 键盘事件的键码 + * @param event 键盘事件的对象 + * @return 如果事件被处理返回true,否则返回false + */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { + // 根据不同的键码做相应的处理 switch (keyCode) { case KeyEvent.KEYCODE_ENTER: + // 当检测到ENTER键时,如果mOnTextViewChangeListener不为空,则不处理事件,交由其他处理程序处理 if (mOnTextViewChangeListener != null) { return false; } break; case KeyEvent.KEYCODE_DEL: + // 当检测到DEL键时,记录删除操作前的光标位置 mSelectionStartBeforeDelete = getSelectionStart(); break; default: + // 对于其他键码,不做特殊处理 break; } + // 对于未特殊处理的键码,调用父类的方法处理 return super.onKeyDown(keyCode, event); } + /** + * 处理键盘按键释放事件 + * + * @param keyCode 按键代码,标识哪个键被释放 + * @param event 键盘事件对象,包含更多关于该事件的详细信息 + * @return 如果事件被处理,返回true;否则返回false + */ @Override public boolean onKeyUp(int keyCode, KeyEvent event) { + // 根据按键代码处理不同的按键事件 switch(keyCode) { case KeyEvent.KEYCODE_DEL: + // 处理删除键释放事件 if (mOnTextViewChangeListener != null) { + // 如果删除前光标位置为0且不是第一个文本框,则通知监听器进行删除操作 if (0 == mSelectionStartBeforeDelete && mIndex != 0) { mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); return true; } } else { + // 如果监听器未设置,则记录日志 Log.d(TAG, "OnTextViewChangeListener was not seted"); } break; case KeyEvent.KEYCODE_ENTER: + // 处理回车键释放事件 if (mOnTextViewChangeListener != null) { + // 获取当前光标位置并分离出光标后的文本,然后设置文本框内容为光标前的文本 int selectionStart = getSelectionStart(); String text = getText().subSequence(selectionStart, length()).toString(); setText(getText().subSequence(0, selectionStart)); + // 通知监听器进行回车操作处理 mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); } else { + // 如果监听器未设置,则记录日志 Log.d(TAG, "OnTextViewChangeListener was not seted"); } break; default: + // 对于其他按键事件,不做任何处理 break; } + // 如果上述条件都不满足,则调用父类的onKeyUp方法处理事件 return super.onKeyUp(keyCode, event); } + /** + * 当视图焦点改变时调用的方法 + * + * @param focused 表示视图是否获得了焦点 + * @param direction 表示焦点移动的方向 + * @param previouslyFocusedRect 表示之前获得焦点的视图的矩形区域 + */ @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { + // 如果有注册的文本视图变更监听器 if (mOnTextViewChangeListener != null) { + // 如果视图失去焦点且文本为空,则调用监听器的onTextChange方法,参数为false if (!focused && TextUtils.isEmpty(getText())) { mOnTextViewChangeListener.onTextChange(mIndex, false); } else { + // 否则,调用监听器的onTextChange方法,参数为true mOnTextViewChangeListener.onTextChange(mIndex, true); } } + // 调用父类的onFocusChanged方法,确保焦点改变的默认行为得以执行 super.onFocusChanged(focused, direction, previouslyFocusedRect); } + /** + * 重写创建上下文菜单的方法 + * 此方法用于在长按文本时创建上下文菜单,根据选中的文本部分是否包含URL来决定菜单项 + * 如果选中的文本中仅包含一个URL,则在菜单中添加一个相应的选项,点击可跳转到该链接 + */ @Override protected void onCreateContextMenu(ContextMenu menu) { + // 检查当前文本是否为Spanned类型,以支持富文本 if (getText() instanceof Spanned) { + // 获取选中文本的起始和结束位置 int selStart = getSelectionStart(); int selEnd = getSelectionEnd(); + // 确定选中文本的最小和最大位置,以处理选中区域 int min = Math.min(selStart, selEnd); int max = Math.max(selStart, selEnd); + // 获取选中文本范围内的所有URLSpan对象 final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); + // 如果选中的文本中仅有一个URL,则进一步处理 if (urls.length == 1) { int defaultResId = 0; + // 遍历预定义的schema-action资源映射,查找匹配的URL schema for(String schema: sSchemaActionResMap.keySet()) { + // 如果URL包含当前schema,则获取对应的资源ID,并停止遍历 if(urls[0].getURL().indexOf(schema) >= 0) { defaultResId = sSchemaActionResMap.get(schema); break; } } + // 如果没有找到匹配的schema,则使用默认的“其他”资源 if (defaultResId == 0) { defaultResId = R.string.note_link_other; } + // 在上下文菜单中添加一个菜单项,并设置点击事件处理 menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { - // goto a new intent + // 点击菜单项时,触发URL的onClick事件,通常会启动一个新的Activity urls[0].onClick(NoteEditText.this); return true; } }); } } + // 调用父类方法,确保菜单被正确创建 super.onCreateContextMenu(menu); } } diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d750e65..c1eddb2 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -63,7 +63,6 @@ \ No newline at end of file diff --git a/desktop.ini b/desktop.ini new file mode 100644 index 0000000..935532c --- /dev/null +++ b/desktop.ini @@ -0,0 +1,6 @@ +[.ShellClassInfo] +IconResource=D:\edge\Folder11-Ico-main\Folder11-Ico-main\ico\xiaomi.ico,0 +[ViewState] +Mode= +Vid= +FolderType=Generic diff --git a/回收站 - 快捷方式.lnk b/回收站 - 快捷方式.lnk new file mode 100644 index 0000000000000000000000000000000000000000..1a744879e24ea9e288e7bb145aa1345c9aea289a GIT binary patch literal 327 zcmeZaU|?VrVFHp236n_j-*aP@D^7mOK!%0P(#rv(%ea3=FbR zK3IYc$oXA!zpg#?o1bMQkOKsbKnyZ*Syr-!?bJ(xTdy%3@V_Z>Ar&Yt2T}ksQ4@%* zfUugujKPG#l)()M4S*~I23;V}fWd;n5XdqFvJ4rVfGkU}yakYD0ECV}2%?REqLx7Q NCJe3&wIHKW006B-FNpvE literal 0 HcmV?d00001