From 1d45b9ea0d510d5017485f5565c2e06e9e74efa2 Mon Sep 17 00:00:00 2001 From: pg8r6bp7v <3050585645@qq.com> Date: Thu, 13 Apr 2023 20:07:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/micode/notes/tool/ResourceParser.java | 19 +++- .../micode/notes/ui/AlarmAlertActivity.java | 103 +++++++++++++++--- .../micode/notes/ui/AlarmInitReceiver.java | 20 +++- .../net/micode/notes/ui/AlarmReceiver.java | 6 + .../net/micode/notes/ui/DateTimePicker.java | 67 ++++++++++-- .../micode/notes/ui/DateTimePickerDialog.java | 30 ++++- .../net/micode/notes/ui/DropdownMenu.java | 10 ++ 7 files changed, 220 insertions(+), 35 deletions(-) diff --git a/src/main/java/net/micode/notes/tool/ResourceParser.java b/src/main/java/net/micode/notes/tool/ResourceParser.java index 1ad3ad6..bf1343a 100644 --- a/src/main/java/net/micode/notes/tool/ResourceParser.java +++ b/src/main/java/net/micode/notes/tool/ResourceParser.java @@ -22,6 +22,21 @@ import android.preference.PreferenceManager; import net.micode.notes.R; import net.micode.notes.ui.NotesPreferenceActivity; +/*简介:字面意义是资源分析器,实际上就是获取资源并且在程序中使用,比如颜色图片等 + * 实现方法:主要利用R.java这个类,其中包括 + * R.id 组件资源引用 + * R.drawable 图片资源 (被使用) + * R.layout 布局资源 + * R.menu 菜单资源 + * R.String 文字资源 + * R.style 主题资源 (被使用) + * 在按顺序设置好相应的id后,就可以编写简单的getXXX函数获取需要的资源 + * + * 特殊的变量 : + * @BG_DEFAULT_COLOR 默认背景颜色(黄) + * BG_DEFAULT_FONT_SIZE 默认文本大小(中) + */ + public class ResourceParser { public static final int YELLOW = 0; @@ -65,9 +80,10 @@ public class ResourceParser { } } + //直接获取默认的背景颜色。 public static int getDefaultBgId(Context context) { if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean( - NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) { + NotesPreferenceActivity.PREFERENCE_SET_BG_COLOR_KEY, false)) { return (int) (Math.random() * NoteBgResources.BG_EDIT_RESOURCES.length); } else { return BG_DEFAULT_COLOR; @@ -162,6 +178,7 @@ public class ResourceParser { R.style.TextAppearanceSuper }; + //这里有一个容错的函数,防止输入的id大于资源总量,若如此,则自动返回默认的设置结果 public static int getTexAppearanceResource(int id) { /** * HACKME: Fix bug of store the resource id in shared preference. diff --git a/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java b/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java index 85723be..3766466 100644 --- a/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java +++ b/src/main/java/net/micode/notes/ui/AlarmAlertActivity.java @@ -41,58 +41,90 @@ import java.io.IOException; public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener { - private long mNoteId; - private String mSnippet; + private long mNoteId; //文本在数据库存储中的ID号 + private String mSnippet;//闹钟提示时出现的文本片段 private static final int SNIPPET_PREW_MAX_LEN = 60; MediaPlayer mPlayer; @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); + 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 { + //根据ID从数据库中获取标签的内容; + //getContentResolver()是实现数据共享,实例存储。 mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1)); mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId); + + //判断标签片段是否达到符合长度 mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, - SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info) - : mSnippet; + SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info) + : mSnippet; + } catch (IllegalArgumentException e) { e.printStackTrace(); return; } - + /* + try + { + // 代码区 + } + catch(Exception e) + { + // 异常处理 + } + 代码区如果有错误,就会返回所写异常的处理。*/ mPlayer = new MediaPlayer(); if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) { + //弹出对话框 showActionDialog(); + + //闹钟提示音激发 playAlarmSound(); + } else { finish(); + //完成闹钟动作 } } private boolean isScreenOn() { + //判断屏幕是否锁屏,调用系统函数判断,最后返回值是布尔类型 PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); return pm.isScreenOn(); } 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); + Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) { mPlayer.setAudioStreamType(silentModeStreams); @@ -100,13 +132,26 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); } try { + //方法:setDataSource(Context context, Uri uri) + //解释:无返回值,设置多媒体数据来源【根据 Uri】 mPlayer.setDataSource(this, url); + + //准备同步 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(); @@ -120,37 +165,67 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD } private void showActionDialog() { + //AlertDialog的构造方法全部是Protected的 + //所以不能直接通过new一个AlertDialog来创建出一个AlertDialog。 + //要创建一个AlertDialog,就要用到AlertDialog.Builder中的create()方法 + //如这里的dialog就是新建了一个AlertDialog AlertDialog.Builder dialog = new AlertDialog.Builder(this); + + //为对话框设置标题 dialog.setTitle(R.string.app_name); + + //为对话框设置内容 dialog.setMessage(mSnippet); + + //给对话框添加"Yes"按钮 dialog.setPositiveButton(R.string.notealert_ok, this); if (isScreenOn()) { dialog.setNegativeButton(R.string.notealert_enter, this); - } + }//对话框添加"No"按钮 dialog.show().setOnDismissListener(this); } public void onClick(DialogInterface dialog, int which) { - switch (which) { + switch (which) {//用which来选择click后下一步的操作 + + //这是取消操作 case DialogInterface.BUTTON_NEGATIVE: + + //实现两个类间的数据传输 Intent intent = new Intent(this, NoteEditActivity.class); + + //设置动作属性 intent.setAction(Intent.ACTION_VIEW); + + //实现key-value对 + //EXTRA_UID为key;mNoteId为键 intent.putExtra(Intent.EXTRA_UID, mNoteId); + + //开始动作 startActivity(intent); break; default: + + //这是确定操作 break; } } - public void onDismiss(DialogInterface dialog) { + public void onDismiss(DialogInterface dialog) {//忽略 + + //停止闹钟声音 stopAlarmSound(); + + //完成该动作 finish(); } private void stopAlarmSound() { if (mPlayer != null) { + //停止播放 mPlayer.stop(); + + //释放MediaPlayer对象 mPlayer.release(); mPlayer = null; } diff --git a/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java b/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java index f221202..5979b2d 100644 --- a/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java +++ b/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java @@ -34,18 +34,23 @@ 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; @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) }, - null); + 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()) { @@ -55,11 +60,14 @@ public class AlarmInitReceiver extends BroadcastReceiver { sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID))); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0); AlarmManager alermManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); + .getSystemService(Context.ALARM_SERVICE); alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); } while (c.moveToNext()); } c.close(); } + //然而通过网上查找资料发现,对于闹钟机制的启动,通常需要上面的几个步骤 + //如新建Intent、PendingIntent以及AlarmManager等 + //这里就是根据数据库里的闹钟时间创建一个闹钟机制 } } diff --git a/src/main/java/net/micode/notes/ui/AlarmReceiver.java b/src/main/java/net/micode/notes/ui/AlarmReceiver.java index 54e503b..90a3b05 100644 --- a/src/main/java/net/micode/notes/ui/AlarmReceiver.java +++ b/src/main/java/net/micode/notes/ui/AlarmReceiver.java @@ -23,8 +23,14 @@ import android.content.Intent; public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { + //启动AlarmAlertActivity intent.setClass(context, AlarmAlertActivity.class); + + //activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈 + //所以要新起一个栈装入启动的activity intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } } +//这是实现alarm这个功能最接近用户层的包,基于上面的两个包, +//作用还需要深究但是对于setClass和addFlags的 \ No newline at end of file diff --git a/src/main/java/net/micode/notes/ui/DateTimePicker.java b/src/main/java/net/micode/notes/ui/DateTimePicker.java index 496b0cd..fa19c82 100644 --- a/src/main/java/net/micode/notes/ui/DateTimePicker.java +++ b/src/main/java/net/micode/notes/ui/DateTimePicker.java @@ -29,9 +29,11 @@ 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; private static final int HOURS_IN_ALL_DAY = 24; private static final int DAYS_IN_ALL_WEEK = 7; @@ -46,10 +48,14 @@ public class DateTimePicker extends FrameLayout { private static final int AMPM_SPINNER_MIN_VAL = 0; private static final int AMPM_SPINNER_MAX_VAL = 1; + //NumberPicker是数字选择器 + //这里定义的四个变量全部是在设置闹钟时需要选择的变量(如日期、时、分、上午或者下午) private final NumberPicker mDateSpinner; private final NumberPicker mHourSpinner; private final NumberPicker mMinuteSpinner; private final NumberPicker mAmPmSpinner; + + //定义了Calendar类型的变量mDate,用于操作时间 private Calendar mDate; private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; @@ -66,6 +72,8 @@ public class DateTimePicker extends FrameLayout { private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() { @Override + //OnValueChangeListener,这是时间改变监听器,这里主要是对日期的监听 + //将现在日期的值传递给mDate;updateDateControl是同步操作 public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); updateDateControl(); @@ -74,37 +82,52 @@ public class DateTimePicker extends FrameLayout { }; private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { + //这里是对 小时(Hour) 的监听 @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { boolean isDateChanged = false; + + //声明一个Calendar的变量cal,便于后续的操作 Calendar cal = Calendar.getInstance(); 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) { + 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; + //这里是对于24小时制时,凌晨11点和12点交替时对日期的更改 } } + //通过数字选择器对newHour的赋值 int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); + + //通过set函数将新的Hour值传给mDate mDate.set(Calendar.HOUR_OF_DAY, newHour); onDateTimeChanged(); if (isDateChanged) { @@ -117,10 +140,14 @@ public class DateTimePicker extends FrameLayout { 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; + int offset = 0;//设置offset,作为小时改变的一个记录数据 + + //如果原值为59,新值为0,则offset加1 + //如果原值为0,新值为59,则offset减 if (oldVal == maxValue && newVal == minValue) { offset += 1; } else if (oldVal == minValue && newVal == maxValue) { @@ -145,6 +172,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; @@ -160,24 +188,31 @@ public class DateTimePicker extends FrameLayout { public interface OnDateTimeChangedListener { void onDateTimeChanged(DateTimePicker view, int year, int month, - int dayOfMonth, int hourOfDay, int minute); + int dayOfMonth, int hourOfDay, int minute); } + //通过对数据库的访问,获取当前的系统时间 public DateTimePicker(Context context) { + this(context, System.currentTimeMillis()); } + //上面函数的得到的是一个天文数字(1970至今的秒数),需要DateFormat将其变得有意义 public DateTimePicker(Context context, long date) { this(context, date, DateFormat.is24HourFormat(context)); } 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); @@ -227,6 +262,8 @@ public class DateTimePicker extends FrameLayout { mIsEnabled = enabled; } + //下面的代码通过原程序的注释已经比较清晰,另外可以通过函数名来判断 + //下面的各函数主要是对上面代码引用到的各函数功能的实现 @Override public boolean isEnabled() { return mIsEnabled; @@ -237,6 +274,8 @@ public class DateTimePicker extends FrameLayout { * * @return the current date in millis */ + + //实现函数——得到当前的秒数 public long getCurrentDateInTimeMillis() { return mDate.getTimeInMillis(); } @@ -246,11 +285,13 @@ public class DateTimePicker extends FrameLayout { * * @param date The current date in millis */ + + //实现函数功能——设置当前的时间,参数是date public void setCurrentDate(long date) { Calendar cal = Calendar.getInstance(); 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)); + cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); } /** @@ -262,8 +303,10 @@ public class DateTimePicker extends FrameLayout { * @param hourOfDay The current hourOfDay * @param minute The current minute */ + + //实现函数功能——设置当前的时间,参数是各详细的变量 public void setCurrentDate(int year, int month, - int dayOfMonth, int hourOfDay, int minute) { + int dayOfMonth, int hourOfDay, int minute) { setCurrentYear(year); setCurrentMonth(month); setCurrentDay(dayOfMonth); @@ -276,6 +319,8 @@ public class DateTimePicker extends FrameLayout { * * @return The current year */ + + //下面是得到year、month、day等值 public int getCurrentYear() { return mDate.get(Calendar.YEAR); } @@ -434,7 +479,7 @@ public class DateTimePicker extends FrameLayout { updateAmPmControl(); } - private void updateDateControl() { + private void updateDateControl() {// 对于星期几的算法 Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1); @@ -448,7 +493,7 @@ public class DateTimePicker extends FrameLayout { mDateSpinner.invalidate(); } - private void updateAmPmControl() { + private void updateAmPmControl() {// 对于上下午操作的算法 if (mIs24HourView) { mAmPmSpinner.setVisibility(View.GONE); } else { @@ -458,7 +503,7 @@ public class DateTimePicker extends FrameLayout { } } - private void updateHourControl() { + private void updateHourControl() {// 对与小时的算法 if (mIs24HourView) { mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW); mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW); @@ -479,7 +524,7 @@ public class DateTimePicker extends FrameLayout { private void onDateTimeChanged() { if (mOnDateTimeChangedListener != null) { mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(), - getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); + getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); } } } diff --git a/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java b/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java index 2c47ba4..2cb7617 100644 --- a/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java @@ -31,9 +31,15 @@ import android.text.format.DateUtils; public class DateTimePickerDialog extends AlertDialog implements OnClickListener { + //创建一个Calendar类型的变量 mDate,方便时间的操作 private Calendar mDate = Calendar.getInstance(); private boolean mIs24HourView; + + //声明一个时间日期滚动选择控件 mOnDateTimeSetListener private OnDateTimeSetListener mOnDateTimeSetListener; + + //DateTimePicker控件,控件一般用于让用户可以从日期列表中选择单个值。 + //运行时,单击控件边上的下拉箭头,会显示为两个部分:一个下拉列表,一个用于选择日期的 private DateTimePicker mDateTimePicker; public interface OnDateTimeSetListener { @@ -41,25 +47,39 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener } 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); + + //将秒数设置为0 mDate.set(Calendar.SECOND, 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()); } @@ -68,19 +88,23 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener mIs24HourView = is24HourView; } + //将时间日期滚动选择控件实例化 public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { mOnDateTimeSetListener = callBack; } + //android开发中常见日期管理工具类(API)——DateUtils:按照上下午显示时间 private void updateTitle(long date) { int flag = DateUtils.FORMAT_SHOW_YEAR | - DateUtils.FORMAT_SHOW_DATE | - DateUtils.FORMAT_SHOW_TIME; + DateUtils.FORMAT_SHOW_DATE | + DateUtils.FORMAT_SHOW_TIME; flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); } + //第一个参数arg0是接收到点击事件的对话框 + //第二个参数arg1是该对话框上的按钮 public void onClick(DialogInterface arg0, int arg1) { if (mOnDateTimeSetListener != null) { mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); diff --git a/src/main/java/net/micode/notes/ui/DropdownMenu.java b/src/main/java/net/micode/notes/ui/DropdownMenu.java index 613dc74..154b906 100644 --- a/src/main/java/net/micode/notes/ui/DropdownMenu.java +++ b/src/main/java/net/micode/notes/ui/DropdownMenu.java @@ -29,14 +29,21 @@ 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; + + //设置这个view的背景 mButton.setBackgroundResource(R.drawable.dropdown_icon); mPopupMenu = new PopupMenu(context, mButton); mMenu = mPopupMenu.getMenu(); + + //MenuInflater是用来实例化Menu目录下的Menu布局文件 + //根据ID来确认menu的内容选项 mPopupMenu.getMenuInflater().inflate(menuId, mMenu); mButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { @@ -45,16 +52,19 @@ public class DropdownMenu { }); } + //设置菜单的监听 public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { if (mPopupMenu != null) { mPopupMenu.setOnMenuItemClickListener(listener); } } + //对于菜单选项的初始化,根据索引搜索菜单需要的选项 public MenuItem findItem(int id) { return mMenu.findItem(id); } + //布局文件,设置标题 public void setTitle(CharSequence title) { mButton.setText(title); } -- 2.34.1