From ee4d22af81e1b18314acc9a3696a2c57a007a262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cfangxiaoting=E2=80=9D?= <“a3197878436@163.com”> Date: Sun, 24 Dec 2023 23:14:54 +0800 Subject: [PATCH 1/2] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 0b0a202fc1cf044593035a9620c024c90146641a Merge: 40aa700 d83102a Author: “fangxiaoting” <“a3197878436@163.com”> Date: Sun Dec 24 21:08:51 2023 +0800 Merge branch 'main' of https://bdgit.educoder.net/pq3fnjual/Minotes into fxt_branch # Conflicts: # doc/实践模板-开源软件泛读、标注和维护报告文档.docx commit 40aa70097752d1c23ebef522932f3d80b69908d1 Author: “fangxiaoting” <“a3197878436@163.com”> Date: Mon Dec 4 10:12:25 2023 +0800 3 commit 553188b1f158a7eb5da90437ae97879fa4695e81 Author: “fangxiaoting” <“a3197878436@163.com”> Date: Mon Dec 4 00:17:54 2023 +0800 2 commit 39fb2ae89773ff1d3b50daec7182019a773c08f4 Author: “fangxiaoting” <“a3197878436@163.com”> Date: Sat Dec 2 21:14:14 2023 +0800 泛读 --- .../micode/notes/ui/DateTimePickerDialog.java | 36 +++--- .../src/net/micode/notes/ui/DropdownMenu.java | 24 ++-- .../micode/notes/ui/FoldersListAdapter.java | 42 +++--- .../src/net/micode/notes/ui/NoteEditText.java | 120 +++++++++++++----- 4 files changed, 141 insertions(+), 81 deletions(-) diff --git a/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java b/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java index 0dcfb80..38726a2 100644 --- a/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java @@ -28,29 +28,29 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.text.format.DateFormat; import android.text.format.DateUtils; - +//功能:创建选择日期和时间的对话框界面,提供日期时间选择和结果回调 public class DateTimePickerDialog extends AlertDialog implements OnClickListener { private Calendar mDate = Calendar.getInstance(); - //һCalendar͵ı mDateʱIJ + //创建一个Calendar类型的变量 mDate,方便时间的操作 private boolean mIs24HourView; private OnDateTimeSetListener mOnDateTimeSetListener; - //һʱڹѡؼ mOnDateTimeSetListener + //声明一个时间日期滚动选择控件 mOnDateTimeSetListener private DateTimePicker mDateTimePicker; - //DateTimePickerؼؼһûԴбѡ񵥸ֵ - //ʱؼϵͷʾΪ֣һбһѡڵ + //DateTimePicker控件,控件一般用于让用户可以从日期列表中选择单个值。 + //运行时,单击控件边上的下拉箭头,会显示为两个部分:一个下拉列表,一个用于选择日期的 public interface OnDateTimeSetListener { void OnDateTimeSet(AlertDialog dialog, long date); } public DateTimePickerDialog(Context context, long date) { - //ԸýԻʵ + //对该界面对话框的实例化 super(context); - //ݿIJ + //对数据库的操作 mDateTimePicker = new DateTimePicker(context); setView(mDateTimePicker); - //һͼ + //添加一个子视图 mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { public void onDateTimeChanged(DateTimePicker view, int year, int month, int dayOfMonth, int hourOfDay, int minute) { @@ -59,30 +59,30 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); mDate.set(Calendar.MINUTE, minute); - //ͼеĸѡΪϵͳǰʱ + //将视图中的各选项设置为系统当前时间 updateTitle(mDate.getTimeInMillis()); } }); mDate.setTimeInMillis(date); - //õϵͳʱ + //得到系统时间 mDate.set(Calendar.SECOND, 0); - //Ϊ0 + //将秒数设置为0 mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); setButton(context.getString(R.string.datetime_dialog_ok), this); setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); - //ðť + //设置按钮 set24HourView(DateFormat.is24HourFormat(this.getContext())); - //ʱ׼ӡ + //时间标准化打印 updateTitle(mDate.getTimeInMillis()); } - + //功能:选择是否使用24小时制 public void set24HourView(boolean is24HourView) { mIs24HourView = is24HourView; } public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { mOnDateTimeSetListener = callBack; - }//ʱڹѡؼʵ + }//将时间日期滚动选择控件实例化 private void updateTitle(long date) { int flag = @@ -91,13 +91,13 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener DateUtils.FORMAT_SHOW_TIME; flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); - }//androidгڹࣨAPIDateUtilsʾʱ + }//android开发中常见日期管理工具类(API)——DateUtils:按照上下午显示时间 public void onClick(DialogInterface arg0, int arg1) { if (mOnDateTimeSetListener != null) { mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); } - }//һarg0ǽյ¼ĶԻ - //ڶarg1ǸöԻϵİť + }//第一个参数arg0是接收到点击事件的对话框 + //第二个参数arg1是该对话框上的按钮 } \ No newline at end of file diff --git a/src/Notes-master/src/net/micode/notes/ui/DropdownMenu.java b/src/Notes-master/src/net/micode/notes/ui/DropdownMenu.java index c8d0835..cf78a7c 100644 --- a/src/Notes-master/src/net/micode/notes/ui/DropdownMenu.java +++ b/src/Notes-master/src/net/micode/notes/ui/DropdownMenu.java @@ -26,40 +26,40 @@ import android.widget.PopupMenu; import android.widget.PopupMenu.OnMenuItemClickListener; import net.micode.notes.R; - +//功能:实现下拉菜单显示和功能 public class DropdownMenu { private Button mButton; private PopupMenu mPopupMenu; - //һ˵ + //声明一个下拉菜单 private Menu mMenu; - + //创建下拉菜单的图形化界面 public DropdownMenu(Context context, Button button, int menuId) { mButton = button; mButton.setBackgroundResource(R.drawable.dropdown_icon); - //viewı + //设置这个view的背景 mPopupMenu = new PopupMenu(context, mButton); mMenu = mPopupMenu.getMenu(); mPopupMenu.getMenuInflater().inflate(menuId, mMenu); - //MenuInflaterʵMenuĿ¼µMenuļ - //IDȷmenuѡ + //MenuInflater是用来实例化Menu目录下的Menu布局文件 + //根据ID来确认menu的内容选项 mButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mPopupMenu.show(); } }); } - + //功能:设置菜单的监听 public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { if (mPopupMenu != null) { mPopupMenu.setOnMenuItemClickListener(listener); - }//ò˵ļ + } } - + //功能:对于菜单选项的初始化,根据索引搜索菜单需要的选项 public MenuItem findItem(int id) { return mMenu.findItem(id); - }//ڲ˵ѡijʼ˵Ҫѡ - + } + //功能:布局文件,设置标题 public void setTitle(CharSequence title) { mButton.setText(title); - }//ļñ + } } \ No newline at end of file diff --git a/src/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java b/src/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java index 96b77da..cbb1ced 100644 --- a/src/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java +++ b/src/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java @@ -15,7 +15,7 @@ */ package net.micode.notes.ui; - + import android.content.Context; import android.database.Cursor; import android.view.View; @@ -23,32 +23,38 @@ import android.view.ViewGroup; import android.widget.CursorAdapter; 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.NoteColumns; - - + +//功能:实现文件夹列表 public class FoldersListAdapter extends CursorAdapter { + //CursorAdapter是Cursor和ListView的接口 + //FoldersListAdapter继承了CursorAdapter的类 + //主要作用是便签数据库和用户的交互 + //这里就是用folder(文件夹)的形式展现给用户 public static final String [] PROJECTION = { NoteColumns.ID, NoteColumns.SNIPPET - }; - + };//调用数据库中便签的ID和片段 + public static final int ID_COLUMN = 0; public static final int NAME_COLUMN = 1; - + public FoldersListAdapter(Context context, Cursor c) { super(context, c); // TODO Auto-generated constructor stub - } - + }//数据库操作 + @Override + //功能:创建一个文件夹,对于各文件夹中子标签的初始化 public View newView(Context context, Cursor cursor, ViewGroup parent) { - return new FolderListItem(context); + //ViewGroup是容器 + return new FolderListItem(context); } - @Override + //功能:将各个布局文件绑定起来 public void bindView(View view, Context context, Cursor cursor) { if (view instanceof FolderListItem) { String folderName = (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context @@ -56,25 +62,27 @@ public class FoldersListAdapter extends CursorAdapter { ((FolderListItem) view).bind(folderName); } } - + //功能:根据数据库中标签的ID得到标签的各项内容 public String getFolderName(Context context, int position) { Cursor cursor = (Cursor) getItem(position); return (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context .getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); } - + //功能:显示文件夹列表内容 private class FolderListItem extends LinearLayout { private TextView mName; - + public FolderListItem(Context context) { super(context); + //操作数据库 inflate(context, R.layout.folder_list_item, this); + //根据布局文件的名字等信息将其找出来 mName = (TextView) findViewById(R.id.tv_folder_name); } - + public void bind(String name) { mName.setText(name); } } - -} + +} \ No newline at end of file diff --git a/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java b/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java index 2afe2a8..d3fa67a 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java +++ b/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java @@ -15,7 +15,7 @@ */ package net.micode.notes.ui; - + import android.content.Context; import android.graphics.Rect; import android.text.Layout; @@ -31,187 +31,239 @@ import android.view.MenuItem; import android.view.MenuItem.OnMenuItemClickListener; import android.view.MotionEvent; import android.widget.EditText; - + import net.micode.notes.R; - + import java.util.HashMap; import java.util.Map; - -public class NoteEditText extends EditText { + +//继承edittext,设置便签设置文本框 +public class NoteEditText extends EditText { private static final String TAG = "NoteEditText"; private int mIndex; private int mSelectionStartBeforeDelete; - + private static final String SCHEME_TEL = "tel:" ; private static final String SCHEME_HTTP = "http:" ; private static final String SCHEME_EMAIL = "mailto:" ; - + + //功能:建立一个字符和整数的hash表,用于链接电话,网站,还有邮箱 private static final Map sSchemaActionResMap = new HashMap(); static { sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web); sSchemaActionResMap.put(SCHEME_EMAIL, R.string.note_link_email); } - + /** * Call by the {@link NoteEditActivity} to delete or add edit text */ + //在NoteEditActivity中删除或添加文本的操作,可以看做是一个文本是否被变的标记,英文注释已说明的很清楚 public interface OnTextViewChangeListener { /** * Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens * and the text is null */ + //处理删除按键时的操作 void onEditTextDelete(int index, String text); - + /** * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} * happen */ + //处理进入按键时的操作 void onEditTextEnter(int index, String text); - + /** * Hide or show item option when text change */ void onTextChange(int index, boolean hasText); } - + private OnTextViewChangeListener mOnTextViewChangeListener; - + + //根据context设置文本 public NoteEditText(Context context) { - super(context, null); + super(context, null);//用super引用父类变量 mIndex = 0; } - + + //设置当前光标 public void setIndex(int index) { mIndex = index; } - + + //初始化文本修改标记 public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { mOnTextViewChangeListener = listener; } - - public NoteEditText(Context context, AttributeSet attrs) { + + //AttributeSet 百度了一下是自定义空控件属性,用于维护便签动态变化的属性 + //初始化便签 + public NoteEditText(Context context, AttributeSet attrs) { super(context, attrs, android.R.attr.editTextStyle); } - + + // 根据defstyle自动初始化 public NoteEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - // TODO Auto-generated constructor stub - } - + // TODO Auto-generated construct or stub + } + @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根据x,y的新值设置新的位置 Layout layout = getLayout(); int line = layout.getLineForVertical(y); int off = layout.getOffsetForHorizontal(line, x); + + //更新光标新的位置 Selection.setSelection(getText(), off); break; } - + return super.onTouchEvent(event); } - + @Override + //函数功能:处理用户按下一个键盘按键时会触发 的事件 public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { + //根据按键的 Unicode 编码值来处理 case KeyEvent.KEYCODE_ENTER: + //“进入”按键 if (mOnTextViewChangeListener != null) { return false; } break; case KeyEvent.KEYCODE_DEL: + //“删除”按键 mSelectionStartBeforeDelete = getSelectionStart(); break; default: break; } + //继续执行父类的其他点击事件 return super.onKeyDown(keyCode, event); } - + @Override + //函数功能:处理用户松开一个键盘按键时会触发 的事件 public boolean onKeyUp(int keyCode, KeyEvent event) { switch(keyCode) { + //根据按键的 Unicode 编码值来处理,有删除和进入2种操作 case KeyEvent.KEYCODE_DEL: if (mOnTextViewChangeListener != null) { + //若是被修改过 if (0 == mSelectionStartBeforeDelete && mIndex != 0) { + //若之前有被修改并且文档不为空 mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); + //利用上文OnTextViewChangeListener对KEYCODE_DEL按键情况的删除函数进行删除 return true; } } else { Log.d(TAG, "OnTextViewChangeListener was not seted"); + //其他情况报错,文档的改动监听器并没有建立 } break; case KeyEvent.KEYCODE_ENTER: + //同上也是分为监听器是否建立2种情况 if (mOnTextViewChangeListener != null) { int selectionStart = getSelectionStart(); + //获取当前位置 String text = getText().subSequence(selectionStart, length()).toString(); + //获取当前文本 setText(getText().subSequence(0, selectionStart)); + //根据获取的文本设置当前文本 mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); + //当{@link KeyEvent#KEYCODE_ENTER}添加新文本 } else { Log.d(TAG, "OnTextViewChangeListener was not seted"); + //其他情况报错,文档的改动监听器并没有建立 } break; default: break; } + //继续执行父类的其他按键弹起的事件 return super.onKeyUp(keyCode, event); } - + @Override + //函数功能:当焦点发生变化时,会自动调用该方法来处理焦点改变的事件 protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { - if (mOnTextViewChangeListener != null) { + if (mOnTextViewChangeListener != null) { + //若监听器已经建立 if (!focused && TextUtils.isEmpty(getText())) { + //获取到焦点并且文本不为空 mOnTextViewChangeListener.onTextChange(mIndex, false); + //mOnTextViewChangeListener子函数,置false隐藏事件选项 } else { mOnTextViewChangeListener.onTextChange(mIndex, true); + //mOnTextViewChangeListener子函数,置true显示事件选项 } } + //继续执行父类的其他焦点变化的事件 super.onFocusChanged(focused, direction, previouslyFocusedRect); } - + @Override + //函数功能:生成上下文菜单 protected void onCreateContextMenu(ContextMenu menu) { if (getText() instanceof Spanned) { + //有文本存在 int selStart = getSelectionStart(); int selEnd = getSelectionEnd(); - + //获取文本开始和结尾位置 + int min = Math.min(selStart, selEnd); int max = Math.max(selStart, selEnd); - + //获取开始到结尾的最大值和最小值 + final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); + //设置url的信息的范围值 if (urls.length == 1) { int defaultResId = 0; for(String schema: sSchemaActionResMap.keySet()) { + //获取计划表中所有的key值 if(urls[0].getURL().indexOf(schema) >= 0) { + //若url可以添加则在添加后将defaultResId置为key所映射的值 defaultResId = sSchemaActionResMap.get(schema); break; } } - + if (defaultResId == 0) { + //defaultResId == 0则说明url并没有添加任何东西,所以置为连接其他SchemaActionResMap的值 defaultResId = R.string.note_link_other; } - + + //建立菜单 menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( new OnMenuItemClickListener() { + //新建按键监听器 public boolean onMenuItemClick(MenuItem item) { // goto a new intent urls[0].onClick(NoteEditText.this); + //根据相应的文本设置菜单的按键 return true; } }); } } + //继续执行父类的其他菜单创建的事件 super.onCreateContextMenu(menu); } -} +} \ No newline at end of file From 80d17e364bcce8423d603332e376c4e55166cfe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E9=AA=81=E7=94=B7?= <860289024@qq.com> Date: Tue, 26 Dec 2023 19:27:56 +0800 Subject: [PATCH 2/2] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 148a3c3784dae9d3f8ad672d50f1352d55c95ce1 Author: 秦骁男 <860289024@qq.com> Date: Tue Dec 26 19:25:59 2023 +0800 1 commit 32d9844272a21c8ef0c8ea8c568f1558baacd5b9 Merge: cde081b d83102a Author: zcx <1078327420@qq.com> Date: Sun Dec 24 21:18:16 2023 +0800 Merge branch 'main' of https://bdgit.educoder.net/pq3fnjual/Minotes into qxn-test commit cde081b96bc94fc71e7900fc6400817f7698db78 Author: zcx <1078327420@qq.com> Date: Sun Dec 24 21:17:43 2023 +0800 1 # Conflicts: # src/Notes-master/src/net/micode/notes/ui/NoteEditText.java --- .../src/net/micode/notes/ui/NoteEditText.java | 38 +++-- .../src/net/micode/notes/ui/NoteItemData.java | 12 +- .../micode/notes/ui/NotesListActivity.java | 149 +++++++++++++++++- .../net/micode/notes/ui/NotesListAdapter.java | 54 ++++++- 4 files changed, 230 insertions(+), 23 deletions(-) diff --git a/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java b/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java index d3fa67a..2f5bdcc 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java +++ b/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java @@ -49,33 +49,31 @@ public class NoteEditText extends EditText { //功能:建立一个字符和整数的hash表,用于链接电话,网站,还有邮箱 private static final Map sSchemaActionResMap = new HashMap(); - static { + static {//一个Map对象,用于储存URI方案和对应的ID,在静态代码中初始化 sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web); sSchemaActionResMap.put(SCHEME_EMAIL, R.string.note_link_email); } /** - * Call by the {@link NoteEditActivity} to delete or add edit text + * 调用来删除或者添加编辑文本 */ //在NoteEditActivity中删除或添加文本的操作,可以看做是一个文本是否被变的标记,英文注释已说明的很清楚 public interface OnTextViewChangeListener { /** - * Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens - * and the text is null + * 删除文本 */ //处理删除按键时的操作 void onEditTextDelete(int index, String text); /** - * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} - * happen + * 添加编辑文本 */ //处理进入按键时的操作 void onEditTextEnter(int index, String text); /** - * Hide or show item option when text change + * 文本更改时隐藏或者显示项目选项 */ void onTextChange(int index, boolean hasText); } @@ -83,7 +81,7 @@ public class NoteEditText extends EditText { private OnTextViewChangeListener mOnTextViewChangeListener; //根据context设置文本 - public NoteEditText(Context context) { + public NoteEditText(Context context) {//当前光标位置是文本开头 super(context, null);//用super引用父类变量 mIndex = 0; } @@ -94,6 +92,9 @@ public class NoteEditText extends EditText { } //初始化文本修改标记 + /** + * 设置文本视图监视器 + */ public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { mOnTextViewChangeListener = listener; } @@ -107,9 +108,12 @@ public class NoteEditText extends EditText { // 根据defstyle自动初始化 public NoteEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - // TODO Auto-generated construct or stub - } - + // 自动生成代码函数存根 + } + + /** + * 根据触摸屏幕的位置,将光标定位到文本对应位置 + */ @Override //功能:处理手机屏幕的所有事件 public boolean onTouchEvent(MotionEvent event) { @@ -137,6 +141,9 @@ public class NoteEditText extends EditText { return super.onTouchEvent(event); } + /** + *按下按键时对回车键和删除键的实现 + */ @Override //函数功能:处理用户按下一个键盘按键时会触发 的事件 public boolean onKeyDown(int keyCode, KeyEvent event) { @@ -159,6 +166,9 @@ public class NoteEditText extends EditText { return super.onKeyDown(keyCode, event); } + /** + * 抬起按键时,队回车键和删除键的特殊处理 + */ @Override //函数功能:处理用户松开一个键盘按键时会触发 的事件 public boolean onKeyUp(int keyCode, KeyEvent event) { @@ -201,6 +211,9 @@ public class NoteEditText extends EditText { return super.onKeyUp(keyCode, event); } + /** + * 处理焦点改变事件,根据焦点状态和文本内容触发相应的回调方法。 + */ @Override //函数功能:当焦点发生变化时,会自动调用该方法来处理焦点改变的事件 protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { @@ -219,6 +232,9 @@ public class NoteEditText extends EditText { super.onFocusChanged(focused, direction, previouslyFocusedRect); } + /** + * 根据选中的URLSpan对象创建上下文菜单,并实现了点击菜单项跳转到对应链接的功能。 + */ @Override //函数功能:生成上下文菜单 protected void onCreateContextMenu(ContextMenu menu) { 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 0f5a878..ec83238 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NoteItemData.java +++ b/src/Notes-master/src/net/micode/notes/ui/NoteItemData.java @@ -27,7 +27,7 @@ import net.micode.notes.tool.DataUtils; public class NoteItemData { - static final String [] PROJECTION = new String [] { + static final String [] PROJECTION = new String [] {//备注的项目 NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID, @@ -41,7 +41,9 @@ public class NoteItemData { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, }; - + /** + * 备注项目的编号 + */ private static final int ID_COLUMN = 0; private static final int ALERTED_DATE_COLUMN = 1; private static final int BG_COLOR_ID_COLUMN = 2; @@ -76,6 +78,9 @@ public class NoteItemData { private boolean mIsOneNoteFollowingFolder; private boolean mIsMultiNotesFollowingFolder; + /** + * 根据数据库游标初始化NoteItemData对象的各个属性值,包括ID、创建日期、背景颜色、小部件ID、小部件类型等。 + */ public NoteItemData(Context context, Cursor cursor) { mId = cursor.getLong(ID_COLUMN); mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN); @@ -109,6 +114,9 @@ public class NoteItemData { checkPostion(cursor); } + /** + * 根据当前游标的位置和类型设置一些标志位属性,用于在后续的逻辑中判断当前笔记的位置和类型。 + */ private void checkPostion(Cursor cursor) { mIsLastItem = cursor.isLast() ? true : false; mIsFirstItem = cursor.isFirst() ? true : false; 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 e843aec..a6baed4 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java +++ b/src/Notes-master/src/net/micode/notes/ui/NotesListActivity.java @@ -78,6 +78,11 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashSet; +/** + * 负责显示笔记和文件夹的列表 + * 管理列表活动的用户界面和用户交互 + * 为查询列表定义了多个变量 + */ public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; @@ -126,7 +131,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private NoteItemData mFocusNoteDataItem; private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?"; - + /** + * 根文件夹的选择 + */ private static final String ROOT_FOLDER_SELECTION = "(" + NoteColumns.TYPE + "<>" + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?)" + " OR (" + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " @@ -142,11 +149,16 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt initResources(); /** - * Insert an introduction when user firstly use this application + * 首次使用时插入介绍 */ setAppInfoFromRawRes(); } + /** + * 检查结果是否正常 + * 正常则重新加载数据 + * 否则调用结果函数 + */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK @@ -157,6 +169,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 检查布尔值是否为错误 + * 如果遇到错误,记录错误信息并返回 + * 在首次运行时将文本保存到程序中 + * 在后续运行中不重复保存 + */ private void setAppInfoFromRawRes() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) { @@ -184,7 +202,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt try { in.close(); } catch (IOException e) { - // TODO Auto-generated catch block + // 自动生成的catch块 e.printStackTrace(); } } @@ -269,6 +287,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return true; } + /** + * 用于更新下拉菜单的显示内容,根据选择的笔记数量更新菜单标题和选项状态 + */ private void updateMenu() { int selectedCount = mNotesListAdapter.getSelectedCount(); // Update dropdown menu @@ -286,32 +307,46 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 与操作模式相关的回调方法,用于处理操作模式的准备和点击事件。 + */ public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - // TODO Auto-generated method stub + // 自动生成的方法存根 return false; } public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - // TODO Auto-generated method stub + return false; } + /** + * 在操作模式销毁时被调用,用于恢复界面状态。 + */ public void onDestroyActionMode(ActionMode mode) { mNotesListAdapter.setChoiceMode(false); mNotesListView.setLongClickable(true); mAddNewNote.setVisibility(View.VISIBLE); } - public void finishActionMode() { + public void finishActionMode() {//用于结束操作模式。 mActionMode.finish(); } + /** + * 处理笔记项选中状态改变的事件,并更新菜单。 + */ public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { mNotesListAdapter.setCheckedItem(position, checked); updateMenu(); } + /** + *处理菜单项点击事件 + * 根据点击的菜单项执行相应的操作 + * 比如删除或移动笔记。 + */ public boolean onMenuItemClick(MenuItem item) { if (mNotesListAdapter.getSelectedCount() == 0) { Toast.makeText(NotesListActivity.this, getString(R.string.menu_select_none), @@ -346,6 +381,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 实现了一个触摸监听器 + * 处理了新建笔记按钮的触摸事件 + * 包括点击透明部分时将事件传递 + */ private class NewNoteOnTouchListener implements OnTouchListener { public boolean onTouch(View v, MotionEvent event) { @@ -408,6 +448,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }; + /** + * 用于开始异步笔记列表查询 + * 根据当前文件夹的不同选择不同的查询条件 + * 并使用后台查询处理程序执行查询操作。 + */ private void startAsyncNotesListQuery() { String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION : NORMAL_SELECTION; @@ -417,6 +462,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC"); } + /** + * 类继承自 AsyncQueryHandler + * 用于处理后台查询的结果 + * 根据查询的不同类型执行相应的操作 + * 比如更新笔记列表或显示文件夹菜单。 + */ private final class BackgroundQueryHandler extends AsyncQueryHandler { public BackgroundQueryHandler(ContentResolver contentResolver) { super(contentResolver); @@ -441,6 +492,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 用于显示文件夹列表菜单,根据传入的游标数据构建对话框,并处理用户选择文件夹的操作。 + */ private void showFolderListMenu(Cursor cursor) { AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this); builder.setTitle(R.string.menu_title_select_folder); @@ -462,6 +516,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt builder.show(); } + /** + * 用于创建新的笔记,构建一个新的笔记编辑界面 + * 并传递文件夹 ID 及请求码进行处理。 + */ private void createNewNote() { Intent intent = new Intent(this, NoteEditActivity.class); intent.setAction(Intent.ACTION_INSERT_OR_EDIT); @@ -469,6 +527,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt this.startActivityForResult(intent, REQUEST_CODE_NEW_NODE); } + /** + * 用于批量删除笔记 + * 根据同步模式的不同执行直接删除或移动到垃圾箱 + * 并在后台执行异步任务。 + */ private void batchDelete() { new AsyncTask>() { protected HashSet doInBackground(Void... unused) { @@ -506,6 +569,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }.execute(); } + /** + * 用于删除文件夹,根据同步模式的不同执行直接删除或移动到垃圾箱,并更新相关的小部件。 + */ private void deleteFolder(long folderId) { if (folderId == Notes.ID_ROOT_FOLDER) { Log.e(TAG, "Wrong folder id, should not happen " + folderId); @@ -533,13 +599,20 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 用于打开笔记,构建一个笔记查看界面 + * 并传递笔记 ID 进行处理。 + */ private void openNode(NoteItemData data) { Intent intent = new Intent(this, NoteEditActivity.class); intent.setAction(Intent.ACTION_VIEW); intent.putExtra(Intent.EXTRA_UID, data.getId()); this.startActivityForResult(intent, REQUEST_CODE_OPEN_NODE); } - + /** + * 用于打开文件夹,根据文件夹的不同执行异步笔记列表查询 + * 并更新界面状态和标题栏的显示。 + */ private void openFolder(NoteItemData data) { mCurrentFolderId = data.getId(); startAsyncNotesListQuery(); @@ -567,6 +640,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 显示软键盘 + */ + private void showSoftInput() { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (inputMethodManager != null) { @@ -574,11 +651,20 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 隐藏软键盘 + */ private void hideSoftInput(View view) { InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); } + /** + * 用于显示创建或修改文件夹的对话框 + * 根据传入的布尔值决定是创建还是修改文件夹 + * 对话框中包含了编辑文本框和确认/取消按钮 + * 并根据用户输入进行相应的操作。 + */ private void showCreateOrModifyFolderDialog(final boolean create) { final AlertDialog.Builder builder = new AlertDialog.Builder(this); View view = LayoutInflater.from(this).inflate(R.layout.dialog_edit_text, null); @@ -664,6 +750,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }); } + /** + * 用于处理返回按钮的操作,根据当前状态执行不同的操作 + * 包括返回上一级文件夹、返回笔记列表或者执行默认的返回操作。 + */ @Override public void onBackPressed() { switch (mState) { @@ -688,6 +778,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } } + /** + * 用于更新小部件,根据传入的小部件 ID 和小部件类型创建相应的意图,并发送广播来更新小部件。 + */ private void updateWidget(int appWidgetId, int appWidgetType) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); if (appWidgetType == Notes.TYPE_WIDGET_2X) { @@ -707,6 +800,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt setResult(RESULT_OK, intent); } + /** + * 是一个上下文菜单的创建监听器,用于创建文件夹的上下文菜单 + * 包括查看文件夹、删除文件夹和修改文件夹名称等选项。 + */ private final OnCreateContextMenuListener mFolderOnCreateContextMenuListener = new OnCreateContextMenuListener() { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { if (mFocusNoteDataItem != null) { @@ -718,6 +815,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } }; + /** + * 用于在上下文菜单关闭时执行操作 + * 它会在菜单关闭时将上下文菜单的创建监听器设置为null。 + */ @Override public void onContextMenuClosed(Menu menu) { if (mNotesListView != null) { @@ -726,6 +827,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt super.onContextMenuClosed(menu); } + /** + * 用于处理上下文菜单中的菜单项选择操作,根据用户选择执行相应的操作 + * 包括打开文件夹、删除文件夹和修改文件夹名称等。 + */ @Override public boolean onContextItemSelected(MenuItem item) { if (mFocusNoteDataItem == null) { @@ -760,6 +865,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return true; } + /** + * 用于准备选项菜单,根据当前状态加载不同的菜单项 + * 包括笔记列表、子文件夹、通话记录文件夹等状态下的菜单项。 + */ @Override public boolean onPrepareOptionsMenu(Menu menu) { menu.clear(); @@ -778,6 +887,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return true; } + /** + * 用于处理选项菜单中的菜单项选择操作,根据用户选择执行相应的操作 + * 包括创建新文件夹、导出笔记到文本、同步、设置、创建新笔记和搜索等。 + */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { @@ -818,12 +931,18 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt return true; } + /** + * 用于处理搜索请求,启动搜索功能。 + */ @Override public boolean onSearchRequested() { startSearch(null, false, null /* appData */, false); return true; } + /** + * 用于将笔记导出为文本文件,在后台执行导出操作 + */ private void exportNoteToText() { final BackupUtils backup = BackupUtils.getInstance(NotesListActivity.this); new AsyncTask() { @@ -866,16 +985,25 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt }.execute(); } + /** + * 用于检查是否处于同步模式,它会获取同步账户名称并检查其长度是否大于0,如果大于0则表示处于同步模式。 + */ private boolean isSyncMode() { return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; } + /** + * 用于启动偏好设置活动,它会创建一个意图并启动偏好设置活动。 + */ private void startPreferenceActivity() { Activity from = getParent() != null ? getParent() : this; Intent intent = new Intent(from, NotesPreferenceActivity.class); from.startActivityIfNeeded(intent, -1); } + /** + * 用于处理列表项的点击操作。根据当前状态和列表项的类型执行相应的操作,包括打开文件夹、打开笔记等。 + */ private class OnListItemClickListener implements OnItemClickListener { public void onItemClick(AdapterView parent, View view, int position, long id) { @@ -917,6 +1045,9 @@ 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: @@ -935,6 +1066,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt NoteColumns.MODIFIED_DATE + " DESC"); } + /** + * 用于处理列表项的长按操作,根据列表项的类型执行相应的操作,包括进入选择模式、执行长按操作等。 + * @return + */ public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { if (view instanceof NotesListItem) { mFocusNoteDataItem = ((NotesListItem) view).getItemData(); 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 51c9cb9..bceae25 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java +++ b/src/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java @@ -30,7 +30,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; - +/** + * 继承自 CursorAdapter,用于管理笔记列表的显示和选择操作 + */ public class NotesListAdapter extends CursorAdapter { private static final String TAG = "NotesListAdapter"; private Context mContext; @@ -38,11 +40,14 @@ public class NotesListAdapter extends CursorAdapter { private int mNotesCount; private boolean mChoiceMode; - public static class AppWidgetAttribute { + public static class AppWidgetAttribute {//用于表示小部件的属性,包括小部件的ID和类型。 public int widgetId; public int widgetType; }; + /** + * 用于初始化适配器,包括初始化上下文、选择索引等。 + */ public NotesListAdapter(Context context) { super(context, null); mSelectedIndex = new HashMap(); @@ -50,11 +55,17 @@ public class NotesListAdapter extends CursorAdapter { mNotesCount = 0; } + /** + * 用于创建新的列表项视图。 + */ @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return new NotesListItem(context); } + /** + * 用于绑定数据到列表项视图。 + */ @Override public void bindView(View view, Context context, Cursor cursor) { if (view instanceof NotesListItem) { @@ -64,20 +75,32 @@ public class NotesListAdapter extends CursorAdapter { } } + /** + * 用于设置指定位置的列表项的选择状态,并刷新视图。 + */ public void setCheckedItem(final int position, final boolean checked) { mSelectedIndex.put(position, checked); notifyDataSetChanged(); } + /** + * 用于检查是否处于选择模式。 + */ public boolean isInChoiceMode() { return mChoiceMode; } + /** + * 用于设置选择模式。 + */ public void setChoiceMode(boolean mode) { mSelectedIndex.clear(); mChoiceMode = mode; } + /** + * 用于选择或取消选择所有列表项。 + */ public void selectAll(boolean checked) { Cursor cursor = getCursor(); for (int i = 0; i < getCount(); i++) { @@ -89,6 +112,9 @@ public class NotesListAdapter extends CursorAdapter { } } + /** + * 用于获取选择的列表项的ID集合。 + */ public HashSet getSelectedItemIds() { HashSet itemSet = new HashSet(); for (Integer position : mSelectedIndex.keySet()) { @@ -105,6 +131,9 @@ public class NotesListAdapter extends CursorAdapter { return itemSet; } + /** + * 用于获取选择的小部件集合。 + */ public HashSet getSelectedWidget() { HashSet itemSet = new HashSet(); for (Integer position : mSelectedIndex.keySet()) { @@ -128,6 +157,9 @@ public class NotesListAdapter extends CursorAdapter { return itemSet; } + /** + * 用于获取当前选中的列表项数量。 + */ public int getSelectedCount() { Collection values = mSelectedIndex.values(); if (null == values) { @@ -143,11 +175,17 @@ public class NotesListAdapter extends CursorAdapter { return count; } + /** + * 用于检查是否所有列表项都被选中。 + */ public boolean isAllSelected() { int checkedCount = getSelectedCount(); return (checkedCount != 0 && checkedCount == mNotesCount); } + /** + * 用于检查指定位置的列表项是否被选中。 + */ public boolean isSelectedItem(final int position) { if (null == mSelectedIndex.get(position)) { return false; @@ -155,18 +193,28 @@ public class NotesListAdapter extends CursorAdapter { return mSelectedIndex.get(position); } + /** + * 在数据内容发生变化时被调用 + * 用于重新计算笔记数量 + */ @Override protected void onContentChanged() { super.onContentChanged(); calcNotesCount(); } - + /** + * 在切换数据源时被调用 + * 用于重新计算笔记数量 + */ @Override public void changeCursor(Cursor cursor) { super.changeCursor(cursor); calcNotesCount(); } + /** + *用于计算笔记的数量,它遍历所有的列表项并统计笔记的数量。 + */ private void calcNotesCount() { mNotesCount = 0; for (int i = 0; i < getCount(); i++) {