From 6b5b66f9b228c62a70b52ee545d6532383f108fc Mon Sep 17 00:00:00 2001 From: lyt <1905191745@qq.com> Date: Wed, 27 Dec 2023 23:48:45 +0800 Subject: [PATCH] =?UTF-8?q?'=E5=89=8D7=E4=B8=AA'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../micode/notes/ui/AlarmAlertActivity.java | 157 ++++++++++++++++-- .../micode/notes/ui/AlarmInitReceiver.java | 40 ++++- .../net/micode/notes/ui/AlarmReceiver.java | 25 +++ .../net/micode/notes/ui/DateTimePicker.java | 93 +++++++++-- .../micode/notes/ui/DateTimePickerDialog.java | 34 +++- .../net/micode/notes/ui/DropdownMenu.java | 26 ++- .../micode/notes/ui/FoldersListAdapter.java | 43 ++++- 7 files changed, 373 insertions(+), 45 deletions(-) diff --git a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java index 85723be..5efc4c0 100644 --- a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java +++ b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java @@ -39,61 +39,119 @@ import net.micode.notes.tool.DataUtils; import java.io.IOException; - -public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener { - private long mNoteId; - private String mSnippet; +/** + * + * @ProjectName: + * @Package: net.micode.notes.ui + * @ClassName: AlarmAlertActivity + * @Description: AlarmAlertActivity类的作用是作为一个提醒警报的活动界面。 + * 当便签的提醒功能触发时,系统会启动AlarmAlertActivity,显示提醒的详细内容和相关操作选项, + * 让用户可以对提醒进行处理,比如查看提醒内容、延迟提醒或者标记为已完成等操作。 + * 这个类主要负责提醒相关的界面展示和用户交互逻辑。 + * @CreateDate: 2023-12-24 10:33 + * @UpdateUser: 更新者: + * @UpdateDate: 2023-12-24 10:33 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ + public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener { + private long mNoteId; //文本在数据库存储中的ID号 + private String mSnippet; //闹钟提示时出现的文本片段 private static final int SNIPPET_PREW_MAX_LEN = 60; MediaPlayer mPlayer; + + /** + * @method onCreate + * @description : + * 初始化提醒界面的布局和逻辑。 + * 设置窗口特性,请求不显示标题栏,并在锁屏状态下显示提醒界面。 + * 获取传入该活动的Intent对象,并尝试从中获取便签的ID。 + * 使用获取到的便签ID获取便签的摘要信息,并进行相应的处理。 + * 创建一个MediaPlayer对象,用于播放提醒的声音。 + * 检查该便签是否在便签数据库中可见。 + * 如果便签可见,则显示操作对话框,并播放提醒音效。 + * 如果便签不可见,则关闭该界面。 + * @date: 2023-12-24 10:41 + * @param + * @return + */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + //Bundle类型的数据与Map类型的数据相似,都是以key-value的形式存储数据的 + //onsaveInstanceState方法是用来保存Activity的状态的 + //能从onCreate的参数savedInsanceState中获得状态数 requestWindowFeature(Window.FEATURE_NO_TITLE); - + //界面显示——无标题 final Window win = getWindow(); win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); - + if (!isScreenOn()) { win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON + //保持窗体点亮 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON + //将窗体点亮 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON + //允许窗体点亮时锁屏 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); - } - + }//在手机锁屏后如果到了闹钟提示时间,点亮屏幕 + Intent intent = getIntent(); - + try { mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1)); mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId); + //根据ID从数据库中获取标签的内容; + //getContentResolver()是实现数据共享,实例存储。 mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info) : mSnippet; + //判断标签片段是否达到符合长度 } catch (IllegalArgumentException e) { e.printStackTrace(); return; } - + mPlayer = new MediaPlayer(); if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) { showActionDialog(); + //弹出对话框 playAlarmSound(); + //闹钟提示音激发 } else { finish(); + //完成闹钟动作 } } - + + /** + * @method isScreenOn + * @description 判断屏幕是否锁屏,调用系统函数判断 + * @date: 2023-12-24 10:45 + * @param + * @return bool 类型 + */ private boolean isScreenOn() { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); return pm.isScreenOn(); } - + + /** + * @method playAlarmSound + * @description: + * 该段代码的作用是根据用户的设置,播放系统默认的闹钟铃声。 + * 并且可以支持在静音模式下播放闹钟铃声 + * @date: 2023-12-24 10:47 + * @param + * @return + */ private void playAlarmSound() { Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM); - + //调用系统的铃声管理URI,得到闹钟提示音 int silentModeStreams = Settings.System.getInt(getContentResolver(), Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); - + if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) { mPlayer.setAudioStreamType(silentModeStreams); } else { @@ -101,12 +159,19 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD } try { mPlayer.setDataSource(this, url); + //方法:setDataSource(Context context, Uri uri) + //解释:无返回值,设置多媒体数据来源【根据 Uri】 mPlayer.prepare(); + //准备同步 mPlayer.setLooping(true); + //设置是否循环播放 mPlayer.start(); + //开始播放 } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); + //e.printStackTrace()函数功能是抛出异常, 还将显示出更深的调用信息 + //System.out.println(e),这个方法打印出异常,并且输出在哪里出现的异常 } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -119,39 +184,95 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD } } + + /** + * @method showActionDialog + * @description + * 创建一个AlertDialog.Builder对象,并设置对话框的标题为应用的名称(R.string.app_name)。 + * 将对话框的消息内容设置为mSnippet变量所存储的文本信息。 + * 设置对话框的积极按钮(Positive Button)的文本为“确定”(R.string.notealert_ok),并将当前类作为按钮的点击监听器。 + * 如果屏幕处于开启状态(通过isScreenOn()方法判断),则设置对话框的消极按钮(Negative Button)的文本为“进入”(R.string.notealert_enter),并将当前类作为按钮的点击监听器。 + * 调用dialog.show().setOnDismissListener(this)方法显示对话框,并设置当前类作为对话框消失时的监听器。 + * @date: 2023-12-24 10:51 + * @param + * @return + */ private void showActionDialog() { AlertDialog.Builder dialog = new AlertDialog.Builder(this); + /* + * AlertDialog的构造方法全部是Protected的 + * 所以不能直接通过new一个AlertDialog来创建出一个AlertDialog。 + * 要创建一个AlertDialog,就要用到AlertDialog.Builder中的create()方法 + * 如这里的dialog就是新建了一个AlertDialog + */ dialog.setTitle(R.string.app_name); + //为对话框设置标题 dialog.setMessage(mSnippet); + //为对话框设置内容 dialog.setPositiveButton(R.string.notealert_ok, this); + //给对话框添加"Yes"按钮 if (isScreenOn()) { dialog.setNegativeButton(R.string.notealert_enter, this); - } + }//对话框添加"No"按钮 dialog.show().setOnDismissListener(this); } - + + /** + * @method onClick + * @description : + * 根据点击的按钮类型执行相应的操作, + * 如果点击的是对话框中的消极按钮,则打开一个新的便签编辑界面,并将当前笔记的id传递给该Activity。 + * @date: 2023-12-24 10:55 + * @param + * @return + */ public void onClick(DialogInterface dialog, int which) { switch (which) { + //用which来选择click后下一步的操作 case DialogInterface.BUTTON_NEGATIVE: + //这是取消操作 Intent intent = new Intent(this, NoteEditActivity.class); + //实现两个类间的数据传输 intent.setAction(Intent.ACTION_VIEW); + //设置动作属性 intent.putExtra(Intent.EXTRA_UID, mNoteId); + //实现key-value对 + //EXTRA_UID为key;mNoteId为键 startActivity(intent); + //开始动作 break; default: + //这是确定操作' break; } } - + + /** + * @method onDismiss + * @description 在闹钟提醒对话框消失时,停止闹钟铃声并结束当前Activity的生命周期。 + * @date: 2023-12-24 10:57 + * @param + * @return + */ public void onDismiss(DialogInterface dialog) { stopAlarmSound(); + //停止闹钟声音 finish(); + //完成该动作 } - + /** + * @method stopAlarmSound + * @description 停止正在播放的闹钟声音,并释放相关的资源。 + * @date: 2023-12-24 10:58 + * @param + * @return + */ private void stopAlarmSound() { if (mPlayer != null) { mPlayer.stop(); + //停止播放 mPlayer.release(); + //释放MediaPlayer对象 mPlayer = null; } } diff --git a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java index f221202..e04df21 100644 --- a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java +++ b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java @@ -27,6 +27,21 @@ import android.database.Cursor; import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.NoteColumns; +/** + * + * @ProjectName: + * @Package: net.micode.notes.ui + * @ClassName: AlarmInitReceiver + * @Description: AlarmInitReceiver类是小米便签应用中的一个广播接收器(BroadcastReceiver) + * 其作用是在设备启动时接收系统发送的广播,并执行一些初始化操作 + * @Author: xumingyang + * @CreateDate: 2023-12-24 11:11 + * @UpdateUser: 更新者: + * @UpdateDate: 2023-12-24 11:11 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ + public class AlarmInitReceiver extends BroadcastReceiver { @@ -34,19 +49,35 @@ public class AlarmInitReceiver extends BroadcastReceiver { NoteColumns.ID, NoteColumns.ALERTED_DATE }; - + //对数据库的操作,调用标签ID和闹钟时间 private static final int COLUMN_ID = 0; private static final int COLUMN_ALERTED_DATE = 1; + + /** + * @method onReceive + * @description 是在设备启动后,通过查询数据库找到需要提醒的标签,并设置对应的闹钟。 + * 这样,在设备启动完成后,小米便签应用可以重新加载标签的提醒功能,确保按时提醒用户。 + * @date: 2023-12-24 11:26 + * @author: lyt + * @param *Cursor在这里的作用是通过查找数据库中的标签内容,找到和当前系统时间相等的标签 + * 从游标中获取提醒日期(alertDate) + * 创建一个新的Intent对象(sender),并指定目标广播接收器(AlarmReceiver) + * 创建PendingIntent:使用getBroadcast()方法创建一个用于启动广播的PendingIntent对象(pendingIntent) + * @return 查询结果将以Cursor对象(c)返回 + */ @Override public void onReceive(Context context, Intent intent) { long currentDate = System.currentTimeMillis(); + //System.currentTimeMillis()产生一个当前的毫秒 + //这个毫秒其实就是自1970年1月1日0时起的毫秒数 Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, PROJECTION, NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, new String[] { String.valueOf(currentDate) }, + //将long变量currentDate转化为字符串 null); - + //Cursor在这里的作用是通过查找数据库中的标签内容,找到和当前系统时间相等的标签 if (c != null) { if (c.moveToFirst()) { do { @@ -62,4 +93,9 @@ public class AlarmInitReceiver extends BroadcastReceiver { c.close(); } } + /* + * 然而通过网上查找资料发现,对于闹钟机制的启动,通常需要上面的几个步骤 + * 如新建Intent、PendingIntent以及AlarmManager等 + * 这里就是根据数据库里的闹钟时间创建一个闹钟机制 + */ } diff --git a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java index 54e503b..1176f83 100644 --- a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java +++ b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java @@ -20,11 +20,36 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +/** + * + * @ProjectName: + * @Package: net.micode.notes.ui + * @ClassName: AlarmReceiver + * @Description: 通过AlarmReceiver类,可以实现小米便签的提醒功能, + * 让用户按时收到提醒并进行相应的操作。 + * @Author: liyiting + * @CreateDate: 2023-12-24 12:46 + * @UpdateUser: 更新者: + * @UpdateDate: 2023-12-24 12:46 + * @UpdateRemark: 更新说明: + */ + + + /** + * @method + * @description 段代码是用于在接收到广播时启动AlarmAlertActivity活动,并在新的任务栈中展示该活动 + * @param *Context context和Intent intent,其中context表示上下文环境,intent表示接收到的广播意图。 + * @return + */ public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { + //重写了onReceive()方法,该方法在接收到广播时会被调用 intent.setClass(context, AlarmAlertActivity.class); + ////启动AlarmAlertActivity intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + ////activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈 + //所以要新起一个栈装入启动的activity context.startActivity(intent); } } diff --git a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DateTimePicker.java b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DateTimePicker.java index 496b0cd..beb94df 100644 --- a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DateTimePicker.java +++ b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DateTimePicker.java @@ -28,8 +28,22 @@ import android.view.View; import android.widget.FrameLayout; import android.widget.NumberPicker; +/** + * + * @ProjectName: + * @Package: net.micode.notes.ui + * @ClassName: DateTimePicker + * @Description: 用于选择日期和时间的自定义视图,包括年、月、日、时、分等选择器。 + * 它使用了NumberPicker控件来实现日期和时间的选择功能,并提供了一些回调接口以便在日期和时间改变时进行通知。 + * @CreateDate: 2023-12-24 12:58 + * @UpdateUser: 更新者: + * @UpdateDate: 2023-12-24 12:58 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ public class DateTimePicker extends FrameLayout { - + //FrameLayout是布局模板之一 + //所有的子元素全部在屏幕的右上方 private static final boolean DEFAULT_ENABLE_STATE = true; private static final int HOURS_IN_HALF_DAY = 12; @@ -45,13 +59,15 @@ public class DateTimePicker extends FrameLayout { private static final int MINUT_SPINNER_MAX_VAL = 59; private static final int AMPM_SPINNER_MIN_VAL = 0; private static final int AMPM_SPINNER_MAX_VAL = 1; - + //初始化控件 private final NumberPicker mDateSpinner; private final NumberPicker mHourSpinner; private final NumberPicker mMinuteSpinner; private final NumberPicker mAmPmSpinner; + //NumberPicker是数字选择器 + //这里定义的四个变量全部是在设置闹钟时需要选择的变量(如日期、时、分、上午或者下午) private Calendar mDate; - + //定义了Calendar类型的变量mDate,用于操作时间 private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; private boolean mIsAm; @@ -72,8 +88,21 @@ public class DateTimePicker extends FrameLayout { onDateTimeChanged(); } }; + //OnValueChangeListener,这是时间改变监听器,这里主要是对日期的监听 + //将现在日期的值传递给mDate;updateDateControl是同步操作 private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { + //这里是对 小时(Hour) 的监听 + + /** + * @method onValueChange + * @description 这段代码是一个回调函数,用于监听NumberPicker的数值改变事件。 + * 当用户改变了时间选择器中的小时数时,就会触发这个回调函数。 + * 在函数中,首先判断当前选择器是否为24小时制,如果不是则需要处理上下午的切换和跨天的情况。 + * @date: 2023-12-24 13:03 + * @param *声明一个Calendar的变量cal,便于后续的操作 + * @return isdateChanged bool类型 判断是否需要对时间进行调整 + */ @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { boolean isDateChanged = false; @@ -83,29 +112,33 @@ public class DateTimePicker extends FrameLayout { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); isDateChanged = true; + //这里是对于12小时制时,晚上11点和12点交替时对日期的更改 } else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, -1); isDateChanged = true; - } + }//这里是对于12小时制时,晚上11点和12点交替时对日期的更改 if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY || oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { mIsAm = !mIsAm; updateAmPmControl(); - } + }//这里是对于12小时制时,中午11点和12点交替时对AM和PM的更改 } else { if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); isDateChanged = true; + //这里是对于24小时制时,晚上11点和12点交替时对日期的更改 } else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, -1); isDateChanged = true; } - } + }//这里是对于12小时制时,凌晨11点和12点交替时对日期的更改 int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); + //通过数字选择器对newHour的赋值 mDate.set(Calendar.HOUR_OF_DAY, newHour); + //通过set函数将新的Hour值传给mDate onDateTimeChanged(); if (isDateChanged) { setCurrentYear(cal.get(Calendar.YEAR)); @@ -116,16 +149,25 @@ public class DateTimePicker extends FrameLayout { }; private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { + /** + * @method onValueChange + * @description 用于监控 NumberPicker(数字选择器)的数值变化事件。 + * 具体来说,这个监听器是用于监听分钟选择器的数值变化。 + * @param *三个参数:picker(当前的 NumberPicker 对象)、oldVal(旧值)和 newVal(新值) + */ @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { int minValue = mMinuteSpinner.getMinValue(); int maxValue = mMinuteSpinner.getMaxValue(); int offset = 0; + //设置offset,作为小时改变的一个记录数据 if (oldVal == maxValue && newVal == minValue) { offset += 1; } else if (oldVal == minValue && newVal == maxValue) { offset -= 1; } + //如果原值为59,新值为0,则offset加1 + //如果原值为0,新值为59,则offset减1 if (offset != 0) { mDate.add(Calendar.HOUR_OF_DAY, offset); mHourSpinner.setValue(getCurrentHour()); @@ -145,9 +187,15 @@ public class DateTimePicker extends FrameLayout { }; private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { + /** + * @method onValueChange + * @description 实现了一个监听器,用于监测用户对NumberPicker控件数值的改变, + * 并根据改变的数值来更新界面上的上午/下午控件 + */ @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mIsAm = !mIsAm; + //对AM和PM的监听 if (mIsAm) { mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY); } else { @@ -166,18 +214,25 @@ public class DateTimePicker extends FrameLayout { public DateTimePicker(Context context) { this(context, System.currentTimeMillis()); } + //通过对数据库的访问,获取当前的系统时间 public DateTimePicker(Context context, long date) { this(context, date, DateFormat.is24HourFormat(context)); } + //上面函数的得到的是一个天文数字(1970至今的秒数),需要DateFormat将其变得有意义 public DateTimePicker(Context context, long date, boolean is24HourView) { super(context); + //获取系统时间 mDate = Calendar.getInstance(); mInitialising = true; mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; inflate(context, R.layout.datetime_picker, this); - + /* + * 如果当前Activity里用到别的layout,比如对话框layout + * 还要设置这个layout上的其他组件的内容,就必须用inflate()方法先将对话框的layout找出来 + * 然后再用findViewById()找到它上面的其它组件 + */ mDateSpinner = (NumberPicker) findViewById(R.id.date); mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); @@ -214,17 +269,28 @@ public class DateTimePicker extends FrameLayout { mInitialising = false; } + /** + * @method setEnabled + * @description 这个函数用于统一设置控件及其相关子控件的可用状态,并且会根据传入的参数值进行相应的操作 + * @param *布尔值 enabled,用于指定控件是否可用。 + * @return 将 mIsEnabled 的值更新为传入的 enabled,以保持状态同步 + */ @Override public void setEnabled(boolean enabled) { if (mIsEnabled == enabled) { return; } + /* + * 如果传入的参数 enabled 与当前的控件可用状态 mIsEnabled 相同,则无需进行任何操作,直接返回。 + * 这样可以避免重复设置控件的可用状态。 + */ super.setEnabled(enabled); mDateSpinner.setEnabled(enabled); mMinuteSpinner.setEnabled(enabled); mHourSpinner.setEnabled(enabled); mAmPmSpinner.setEnabled(enabled); mIsEnabled = enabled; + //将 mIsEnabled 的值更新为传入的 enabled,以保持状态同步 } @Override @@ -239,7 +305,7 @@ public class DateTimePicker extends FrameLayout { */ public long getCurrentDateInTimeMillis() { return mDate.getTimeInMillis(); - } + }//实现函数——得到当前的秒数 /** * Set the current date @@ -251,7 +317,7 @@ public class DateTimePicker extends FrameLayout { cal.setTimeInMillis(date); setCurrentDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); - } + }//实现函数功能——设置当前的时间,参数是date /** * Set the current date @@ -269,13 +335,14 @@ public class DateTimePicker extends FrameLayout { setCurrentDay(dayOfMonth); setCurrentHour(hourOfDay); setCurrentMinute(minute); - } + }//实现函数功能——设置当前的时间,参数是各详细的变量 /** * Get current year * * @return The current year */ + //下面是得到year、month、day等值 public int getCurrentYear() { return mDate.get(Calendar.YEAR); } @@ -446,7 +513,7 @@ public class DateTimePicker extends FrameLayout { mDateSpinner.setDisplayedValues(mDateDisplayValues); mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); mDateSpinner.invalidate(); - } + }// 对于星期几的算法 private void updateAmPmControl() { if (mIs24HourView) { @@ -456,7 +523,7 @@ public class DateTimePicker extends FrameLayout { mAmPmSpinner.setValue(index); mAmPmSpinner.setVisibility(View.VISIBLE); } - } + }// 对于上下午操作的算法 private void updateHourControl() { if (mIs24HourView) { @@ -466,7 +533,7 @@ public class DateTimePicker extends FrameLayout { mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); } - } + }// 对与小时的算法 /** * Set the callback that indicates the 'Set' button has been pressed. diff --git a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java index 2c47ba4..c6a5e07 100644 --- a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java @@ -29,21 +29,42 @@ import android.content.DialogInterface.OnClickListener; import android.text.format.DateFormat; import android.text.format.DateUtils; +/** + * + * @ProjectName: DateTimePickerDialog + * @Package: net.micode.notes.ui + * @ClassName: DateTimePickerDialog + * @Description: DateTimePickerDialog 的作用是提供一个日期和时间选择器的对话框,用于让用户选择日期和时间。 + * 该对话框通常用于设置便签的提醒时间或截止时间等功能,用户可以通过滚动选择器来选择特定的日期和时间。 + * DateTimePickerDialog 提供了直观且方便的界面,使用户能够方便地选择所需的日期和时间。 + * @CreateDate: 2023-12-24 13:52 + * @UpdateUser: 更新者: + * @UpdateDate: 2023-12-24 13:52 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ public class DateTimePickerDialog extends AlertDialog implements OnClickListener { private Calendar mDate = Calendar.getInstance(); + //创建一个Calendar类型的变量 mDate,方便时间的操作 private boolean mIs24HourView; private OnDateTimeSetListener mOnDateTimeSetListener; + //声明一个时间日期滚动选择控件 mOnDateTimeSetListener private DateTimePicker mDateTimePicker; + //DateTimePicker控件,控件一般用于让用户可以从日期列表中选择单个值。 + //运行时,单击控件边上的下拉箭头,会显示为两个部分:一个下拉列表,一个用于选择日期的 public interface OnDateTimeSetListener { void OnDateTimeSet(AlertDialog dialog, long date); } public DateTimePickerDialog(Context context, long date) { + //对该界面对话框的实例化 super(context); + //对数据库的操作 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) { @@ -52,15 +73,21 @@ 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 对日期时间进行标准化处理 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()); } @@ -70,7 +97,7 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { mOnDateTimeSetListener = callBack; - } + }//将时间日期滚动选择控件实例化 private void updateTitle(long date) { int flag = @@ -79,12 +106,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开发中常见日期管理工具类(API)——DateUtils:按照上下午显示时间 public void onClick(DialogInterface arg0, int arg1) { if (mOnDateTimeSetListener != null) { mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); } - } + }//第一个参数arg0是接收到点击事件的对话框 + //第二个参数arg1是该对话框上的按钮 } \ No newline at end of file diff --git a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DropdownMenu.java b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DropdownMenu.java index 613dc74..bf6809e 100644 --- a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DropdownMenu.java +++ b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/DropdownMenu.java @@ -27,17 +27,37 @@ import android.widget.PopupMenu.OnMenuItemClickListener; import net.micode.notes.R; +/** + * + * @ProjectName: + * @Package: net.micode.notes.ui + * @ClassName: DropdownMenu + * @Description: DropdownMenu是一个下拉菜单,它的作用是提供一种选择多个选项的方式。 + * 当用户点击DropdownMenu时,会弹出一个下拉列表,列出了多个选项供用户选择。 + * 1.笔记分类:用户可以使用DropdownMenu来选择笔记的分类,比如工作、生活、学习等,从而方便地将笔记进行分类管理。 + * 2.笔记排序:用户可以使用DropdownMenu来选择笔记的排序方式,比如按时间、按标题等进行排序,以满足不同排序需求。 + * 3.标签管理:用户可以使用DropdownMenu来选择或添加标签,以对笔记进行更细粒度的分类和标记。 + * @CreateDate: 2023-12-24 13:57 + * @UpdateUser: 更新者: + * @UpdateDate: 2023-12-24 13:57 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ 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的背景 mPopupMenu = new PopupMenu(context, mButton); mMenu = mPopupMenu.getMenu(); mPopupMenu.getMenuInflater().inflate(menuId, mMenu); + //MenuInflater是用来实例化Menu目录下的Menu布局文件 + //根据ID来确认menu的内容选项 mButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mPopupMenu.show(); @@ -49,13 +69,13 @@ public class DropdownMenu { if (mPopupMenu != null) { mPopupMenu.setOnMenuItemClickListener(listener); } - } + }//设置菜单的监听 public MenuItem findItem(int id) { return mMenu.findItem(id); } - + //对于菜单选项的初始化,根据索引搜索菜单需要的选项 public void setTitle(CharSequence title) { mButton.setText(title); } -} +}//布局文件,设置标题 diff --git a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java index 96b77da..2da621b 100644 --- a/src/Notes-master1/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java +++ b/src/Notes-master1/app/src/main/java/net/micode/notes/ui/FoldersListAdapter.java @@ -28,25 +28,53 @@ import net.micode.notes.R; import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.NoteColumns; - +/** + * + * @ProjectName: + * @Package: net.micode.notes.ui + * @ClassName: FoldersListAdapter + * @Description: FoldersListAdapter 的作用是作为文件夹列表的适配器,用于管理和显示文件夹列表的数据和视图。 + * @CreateDate: 2023-12-24 14:05 + * @UpdateUser: 更新者: + * @UpdateDate: 2023-12-24 14:05 + * @UpdateRemark: 更新说明: + * @Version: 1.0 + */ 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; + /** + * @method FoldersListAdapter + * @description 用于初始化FoldersListAdapter类的实例。这个类可能是用于管理文件夹列表显示的适配器,其中包含了数据库操作相关的功能 + * @param context 参数通常是指当前的上下文 + * c 参数可能是一个用于查询数据库的Cursor对象。 + */ public FoldersListAdapter(Context context, Cursor c) { super(context, c); // TODO Auto-generated constructor stub - } + }//数据库操作 + /** + * @method newView + * @description 用于创建新的视图用于显示文件夹列表项。 + * @return 将该视图返回给适配器使用 + */ @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return new FolderListItem(context); - } + }//创建一个文件夹,对于各文件夹中子标签的初始化 @Override public void bindView(View view, Context context, Cursor cursor) { @@ -55,20 +83,23 @@ public class FoldersListAdapter extends CursorAdapter { .getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); ((FolderListItem) view).bind(folderName); } - } + }//将各个布局文件绑定起来 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); - } + }//根据数据库中标签的ID得到标签的各项内容 + 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); }