diff --git a/doc/02_小米便签开源代码阅读-精读报告_冷宇阳.docx b/doc/02_小米便签开源代码阅读-精读报告_冷宇阳.docx index 4f8ccd5..faa0562 100644 Binary files a/doc/02_小米便签开源代码阅读-精读报告_冷宇阳.docx and b/doc/02_小米便签开源代码阅读-精读报告_冷宇阳.docx differ diff --git a/src/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java b/src/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java index 6adb702..c75e778 100644 --- a/src/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java +++ b/src/app/src/main/java/net/micode/notes/ui/AlarmReceiver.java @@ -24,7 +24,11 @@ public class AlarmReceiver extends BroadcastReceiver {//闹铃提醒接收器 @Override public void onReceive(Context context, Intent intent) { intent.setClass(context, AlarmAlertActivity.class); + //启动AlarmAlertActivity intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + //activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈所以要新起一个栈装入启动的activity + context.startActivity(intent); } } +//这是实现alarm这个功能最接近用户层的包,基于上面的两个包 diff --git a/src/app/src/main/java/net/micode/notes/ui/DateTimePicker.java b/src/app/src/main/java/net/micode/notes/ui/DateTimePicker.java index a247ebb..9385b93 100644 --- a/src/app/src/main/java/net/micode/notes/ui/DateTimePicker.java +++ b/src/app/src/main/java/net/micode/notes/ui/DateTimePicker.java @@ -29,7 +29,7 @@ import android.widget.FrameLayout; import android.widget.NumberPicker; 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 +45,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,60 +74,72 @@ public class DateTimePicker extends FrameLayout {//设置提醒时间的部件 onDateTimeChanged(); } }; - + //OnValueChangeListener,这是时间改变监听器,这里主要是对日期的监听 + //将现在日期的值传递给mDate;updateDateControl是同步操作 private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { + //这里是对 小时(Hour) 的监听 @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { boolean isDateChanged = false; Calendar cal = Calendar.getInstance(); + //声明一个Calendar的变量cal,便于后续的操作 if (!mIs24HourView) { if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { 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)); setCurrentMonth(cal.get(Calendar.MONTH)); setCurrentDay(cal.get(Calendar.DAY_OF_MONTH)); - } + }//更新日期 } }; private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { @Override + //这里是对 分钟(Minute)改变的监听 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,6 +159,7 @@ public class DateTimePicker extends FrameLayout {//设置提醒时间的部件 }; private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { + //对AM和PM的监听 @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mIsAm = !mIsAm; @@ -166,30 +181,38 @@ 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); - mDateSpinner.setOnValueChangedListener(mOnDateChangedListener); + //从 XML 布局文件中找到一个 ID 为 date 的 NumberPicker 控件,并将其引用赋值给 mDateSpinner + mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL);//最小 + mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL);//最大 + mDateSpinner.setOnValueChangedListener(mOnDateChangedListener);//监听 mHourSpinner = (NumberPicker) findViewById(R.id.hour); mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); + mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL); mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); mMinuteSpinner.setOnLongPressUpdateInterval(100); mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener); + //这段代码是使用 Android 的 NumberPicker 控件来创建三个数字选择器:一个用于日期、一个用于小时、一个用于分钟。 + //这些控件通常用于在一个预定义的范围内选择数字 String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings(); mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm); @@ -198,32 +221,33 @@ public class DateTimePicker extends FrameLayout {//设置提醒时间的部件 mAmPmSpinner.setDisplayedValues(stringsForAmPm); mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener); - // update controls to initial state + // update controls to initial state 将控件更新到初始状态 updateDateControl(); updateHourControl(); updateAmPmControl(); set24HourView(is24HourView); - // set to current time + // set to current time 设置为当前时间 setCurrentDate(date); setEnabled(isEnabled()); - // set the content descriptions + // set the content descriptions 设置内容描述 mInitialising = false; } @Override - public void setEnabled(boolean enabled) { + public void setEnabled(boolean enabled) {//用于设置时间选择器的启用或禁用状态 if (mIsEnabled == enabled) { return; } - super.setEnabled(enabled); + super.setEnabled(enabled);//这行代码调用了当前类的父类中的setEnabled方法,并传递了enabled参数。这确保了父类的状态也被相应地设置。 mDateSpinner.setEnabled(enabled); mMinuteSpinner.setEnabled(enabled); mHourSpinner.setEnabled(enabled); mAmPmSpinner.setEnabled(enabled); + //分别设置了四个不同的spinner的启用状态 mIsEnabled = enabled; } @@ -240,7 +264,7 @@ public class DateTimePicker extends FrameLayout {//设置提醒时间的部件 public long getCurrentDateInTimeMillis() { return mDate.getTimeInMillis(); } - + //实现函数——得到当前的秒数 /** * Set the current date * @@ -251,7 +275,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,7 +293,7 @@ public class DateTimePicker extends FrameLayout {//设置提醒时间的部件 setCurrentDay(dayOfMonth); setCurrentHour(hourOfDay); setCurrentMinute(minute); - } + }//实现函数功能——设置当前的时间,参数是各详细的变量 /** * Get current year @@ -446,7 +470,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 +480,7 @@ public class DateTimePicker extends FrameLayout {//设置提醒时间的部件 mAmPmSpinner.setValue(index); mAmPmSpinner.setVisibility(View.VISIBLE); } - } + }// 对于上下午操作的算法 private void updateHourControl() { if (mIs24HourView) { @@ -466,12 +490,13 @@ 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. * @param callback the callback, if null will do nothing */ + //设置一个回调函数,该回调函数会在“Set”按钮被按下时触发。如果用户没有提供回调函数(即传递了null),则不会执行任何操作。 public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { mOnDateTimeChangedListener = callback; } diff --git a/src/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java b/src/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java index 6f40e05..5e83af2 100644 --- a/src/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/app/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java @@ -32,35 +32,47 @@ import android.text.format.DateUtils; 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) { + int dayOfMonth, int hourOfDay, int minute) { mDate.set(Calendar.YEAR, year); mDate.set(Calendar.MONTH, month); 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,21 +82,21 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { mOnDateTimeSetListener = callBack; - } + }//将时间日期滚动选择控件实例化 private void updateTitle(long date) { int flag = - DateUtils.FORMAT_SHOW_YEAR | - DateUtils.FORMAT_SHOW_DATE | - DateUtils.FORMAT_SHOW_TIME; + DateUtils.FORMAT_SHOW_YEAR | + DateUtils.FORMAT_SHOW_DATE | + DateUtils.FORMAT_SHOW_TIME; flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); - } + }//android开发中常见日期管理工具类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/app/src/main/java/net/micode/notes/ui/NotesListActivity.java b/src/app/src/main/java/net/micode/notes/ui/NotesListActivity.java index bf8cb62..e72bea7 100644 --- a/src/app/src/main/java/net/micode/notes/ui/NotesListActivity.java +++ b/src/app/src/main/java/net/micode/notes/ui/NotesListActivity.java @@ -78,7 +78,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashSet; -public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {//主界面,用于实现处理文件夹列表的活动 +public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { + //主界面,用于实现处理文件夹列表的活动 private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; private static final int FOLDER_LIST_QUERY_TOKEN = 1;