Compare commits

...

3 Commits

Author SHA1 Message Date
Miumizz 80525cffb5 维护报告
1 year ago
syl cd0aa537a9 代码标注“
1 year ago
syl a84438862b 代码标注“
1 year ago

@ -0,0 +1,166 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.ui;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.PowerManager;
import android.provider.Settings;
import android.view.Window;
import android.view.WindowManager;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.tool.DataUtils;
import java.io.IOException;
public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
private long mNoteId; // 声明一个long类型的变量mNoteId
private String mSnippet; // 声明一个String类型的变量mSnippet
private static final int SNIPPET_PREW_MAX_LEN = 60; // 声明一个int类型的变量SNIPPET_PREW_MAX_LEN值为60
MediaPlayer mPlayer; // 声明一个MediaPlayer类型的变量mPlayer
@Override // 重写onCreate方法用于初始化Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置当前Activity的标题为空
final Window win = getWindow(); // 获取当前Activity的Window对象
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); // 设置当前Activity的Window对象的属性使其在锁定状态时保持常亮
if (!isScreenOn()) { // 判断当前屏幕是否处于锁定状态
win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON // 如果当前屏幕处于锁定状态则设置当前Activity的Window对象的属性使其在锁定状态时保持常亮并允许锁定屏幕
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR);
}
Intent intent = getIntent(); // 获取当前Activity的Intent
try {
mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1)); // 从Intent中获取mNoteId
mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId); // 从数据库中获取mSnippet
mSnippet = mSnippet.length() > SNIPPET_PREW_MAX_LEN ? mSnippet.substring(0, // 如果mSnippet的长度大于SNIPPET_PREW_MAX_LEN则截取mSnippet的前SNIPPET_PREW_MAX_LEN个字符并加上getResources().getString(R.string.notelist_string_info)
SNIPPET_PREW_MAX_LEN) + getResources().getString(R.string.notelist_string_info)
: mSnippet;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return;
}
mPlayer = new MediaPlayer(); // 初始化mPlayer
if (DataUtils.visibleInNoteDatabase(getContentResolver(), mNoteId, Notes.TYPE_NOTE)) { // 判断mNoteId对应的Notes表中的TYPE_NOTE字段是否可见
showActionDialog(); // 如果可见则显示ActionDialog
playAlarmSound(); // 播放闹钟音效
} else {
finish(); // 如果不可见则结束当前Activity
}
}
private boolean isScreenOn() { // 判断当前屏幕是否处于锁定状态
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); // 获取当前系统的PowerManager实例
return pm.isScreenOn(); // 判断当前屏幕是否处于锁定状态
}
private void playAlarmSound() { // 播放闹钟音效
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM); // 获取当前系统默认的闹钟铃声
int silentModeStreams = Settings.System.getInt(getContentResolver(), // 获取当前系统设置的静音模式
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) { // 判断当前系统设置的静音模式是否包含AudioManager.STREAM_ALARM
mPlayer.setAudioStreamType(silentModeStreams); // 如果包含则设置mPlayer的音频流类型为silentModeStreams
} else {
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM); // 如果不包含则设置mPlayer的音频流类型为AudioManager.STREAM_ALARM
}
try {
mPlayer.setDataSource(this, url); // 设置mPlayer的数据源
mPlayer.prepare(); // 准备播放
mPlayer.setLooping(true); // 设置mPlayer循环播放
mPlayer.start(); // 开始播放
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void showActionDialog() { // 显示ActionDialog
AlertDialog.Builder dialog = new AlertDialog.Builder(this); // 创建一个AlertDialog.Builder实例
dialog.setTitle(R.string.app_name); // 设置AlertDialog的标题
dialog.setMessage(mSnippet); // 设置AlertDialog的消息
dialog.setPositiveButton(R.string.notealert_ok, this); // 设置AlertDialog的确定按钮
if (isScreenOn()) { // 判断当前屏幕是否处于锁定状态
dialog.setNegativeButton(R.string.notealert_enter, this); // 如果当前屏幕处于锁定状态则设置AlertDialog的取消按钮
}
dialog.show().setOnDismissListener(this); // 显示AlertDialog
}
public void onClick(DialogInterface dialog, int which) { // 重写onClick方法用于处理用户点击Dialog中的按钮
switch (which) {
case DialogInterface.BUTTON_NEGATIVE:
Intent intent = new Intent(this, NoteEditActivity.class); // 创建一个Intent用于启动NoteEditActivity
intent.setAction(Intent.ACTION_VIEW); // 设置Intent的action
intent.putExtra(Intent.EXTRA_UID, mNoteId); // 设置Intent的参数
startActivity(intent); // 启动NoteEditActivity
break;
default:
break;
}
}
public void onDismiss(DialogInterface dialog) { // 重写onDismiss方法用于处理用户关闭Dialog
stopAlarmSound(); // 停止播放闹钟音效
finish(); // 结束当前Activity
}
private void stopAlarmSound() { // 停止播放闹钟音效
if (mPlayer != null) { // 判断mPlayer是否为空
mPlayer.stop(); // 如果不为空,则停止播放
mPlayer.release(); // 释放mPlayer
mPlayer = null; // 将mPlayer置为空
}
}
}

@ -0,0 +1,65 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.ui;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
public class AlarmInitReceiver extends BroadcastReceiver {
private static final String [] PROJECTION = new String [] { // 声明一个私有静态变量PROJECTION它是一个字符串数组其中包含NoteColumns.ID和NoteColumns.ALERTED_DATE两个字符串
NoteColumns.ID,
NoteColumns.ALERTED_DATE
};
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(); //获取当前时间
Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, //查询数据库中alerted_date大于当前时间type为note的记录
PROJECTION,
NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE,
new String[] { String.valueOf(currentDate) },
null);
if (c != null) {
if (c.moveToFirst()) {
do {
long alertDate = c.getLong(COLUMN_ALERTED_DATE); //获取alerted_date
Intent sender = new Intent(context, AlarmReceiver.class); //创建一个Intent用于传递数据
sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID))); //将id传递给AlarmReceiver
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0); //创建一个PendingIntent用于传递Intent
AlarmManager alermManager = (AlarmManager) context //获取AlarmManager实例
.getSystemService(Context.ALARM_SERVICE);
alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); //设置定时器在alerted_date时间点发送pendingIntent
} while (c.moveToNext());
}
c.close();
}
}
}

@ -0,0 +1,31 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.ui;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AlarmReceiver extends BroadcastReceiver { // 创建一个AlarmReceiver类继承自BroadcastReceiver
@Override
public void onReceive(Context context, Intent intent) { // 重写onReceive方法接收Intent类型的参数
intent.setClass(context, AlarmAlertActivity.class); // 设置AlarmAlertActivity的Class
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 设置AlarmAlertActivity的Flag
context.startActivity(intent); // 启动AlarmAlertActivity
}
}

@ -0,0 +1,515 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.ui;
import java.text.DateFormatSymbols;
import java.util.Calendar;
import net.micode.notes.R;
import android.content.Context;
import android.text.format.DateFormat;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.NumberPicker;
public class DateTimePicker extends 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;
private static final int DATE_SPINNER_MIN_VAL = 0;
private static final int DATE_SPINNER_MAX_VAL = DAYS_IN_ALL_WEEK - 1;
private static final int HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW = 0;
private static final int HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW = 23;
private static final int HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW = 1;
private static final int HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW = 12;
private static final int MINUT_SPINNER_MIN_VAL = 0;
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;
private Calendar mDate;
private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK];
private boolean mIsAm;
private boolean mIs24HourView;
private boolean mIsEnabled = DEFAULT_ENABLE_STATE;
private boolean mInitialising;
private OnDateTimeChangedListener mOnDateTimeChangedListener;
private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() { // 创建一个NumberPicker.OnValueChangeListener的匿名内部类用于监听NumberPicker的值改变
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal); // 计算新旧值之间的差值并将其加到mDate中
updateDateControl(); // 更新日期控件
onDateTimeChanged(); // 更新时间控件
}
};
private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
boolean isDateChanged = false;
Calendar cal = Calendar.getInstance();
if (!mIs24HourView) { // 判断是否是24小时制
if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) {
if (mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { // 如果当前是上午且当前小时是half day则设置当前时间为下午
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, 1);
isDateChanged = true;
} else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { // 如果当前是下午且当前小时是half day则设置当前时间为上午
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, -1);
isDateChanged = true;
}
if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY || // 如果当前是上午且当前小时是half day则设置当前时间为下午
oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) {
mIsAm = !mIsAm;
updateAmPmControl();
}
} else {
if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { // 如果当前是24小时制且当前小时是all day则设置当前时间为次日
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, 1);
isDateChanged = true;
}
else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { // 如果当前是24小时制且当前小时是all day则设置当前时间为次日
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, -1);
isDateChanged = true;
}
}
int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); // 获取当前小时
mDate.set(Calendar.HOUR_OF_DAY, newHour); // 设置当前时间
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
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
int minValue = mMinuteSpinner.getMinValue(); // 获取分钟数字选择器的最小值
int maxValue = mMinuteSpinner.getMaxValue(); // 获取分钟数字选择器的最大值
int offset = 0;
if (oldVal == maxValue && newVal == minValue) { // 如果旧的值是最大值新的值是最小值则偏移量加1
offset += 1;
} else if (oldVal == minValue && newVal == maxValue) { // 如果旧的值是最小值新的值是最大值则偏移量减1
offset -= 1;
}
if (offset != 0) { // 如果偏移量不等于0则添加偏移量
mDate.add(Calendar.HOUR_OF_DAY, offset); // 添加偏移量
mHourSpinner.setValue(getCurrentHour()); // 设置小时数字选择器的值
updateDateControl(); // 更新日期控件
int newHour = getCurrentHourOfDay(); // 获取当前的小时
if (newHour >= HOURS_IN_HALF_DAY) { // 如果当前的小时大于等于12则设置AM为false
mIsAm = false;
updateAmPmControl(); // 更新AM/PM控件
} else { // 否则设置AM为true
mIsAm = true;
updateAmPmControl(); // 更新AM/PM控件
}
}
mDate.set(Calendar.MINUTE, newVal); // 设置分钟数字选择器的值
onDateTimeChanged(); // 更新日期控件
}
};
private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
mIsAm = !mIsAm; // 判断当前是上午还是下午
if (mIsAm) { // 根据当前是上午还是下午,调整时间
mDate.add(Calendar.HOUR_OF_DAY, -HOURS_IN_HALF_DAY);
} else {
mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY);
}
updateAmPmControl(); // 更新AM/PM控制
onDateTimeChanged(); // 更新时间
}
};
public interface OnDateTimeChangedListener { // 添加中文注释后
void onDateTimeChanged(DateTimePicker view, int year, int month, // 当时间改变时调用
int dayOfMonth, int hourOfDay, int minute);
}
public DateTimePicker(Context context) { // 构造函数,传入上下文和当前时间戳
this(context, System.currentTimeMillis());
}
public DateTimePicker(Context context, long date) { // 创建一个DateTimePicker对象参数为context和datedateFormat默认为24小时制
this(context, date, DateFormat.is24HourFormat(context));
}
public DateTimePicker(Context context, long date, boolean is24HourView) { // 创建DateTimePicker对象传入上下文、日期和是否24小时视图
super(context);
mDate = Calendar.getInstance();
mInitialising = true;
mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY;
inflate(context, R.layout.datetime_picker, this);
mDateSpinner = (NumberPicker) findViewById(R.id.date); //获取日期选择器
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);
String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings(); // 设置AM/PM选择器
mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm);
mAmPmSpinner.setMinValue(AMPM_SPINNER_MIN_VAL);
mAmPmSpinner.setMaxValue(AMPM_SPINNER_MAX_VAL);
mAmPmSpinner.setDisplayedValues(stringsForAmPm);
mAmPmSpinner.setOnValueChangedListener(mOnAmPmChangedListener);
updateDateControl(); // 更新日期控制
updateHourControl(); // 更新小时控制
updateAmPmControl(); // 更新AM/PM控制
set24HourView(is24HourView); // 设置24小时视图
setCurrentDate(date); // 设置当前日期
setEnabled(isEnabled()); // 设置是否可用
mInitialising = false;
}
@Override
public void setEnabled(boolean enabled) {
if (mIsEnabled == enabled) { // 判断当前状态是否和传入的参数一致
return;
}
super.setEnabled(enabled); // 调用父类的setEnabled方法
mDateSpinner.setEnabled(enabled); // 设置日期选择器是否可用
mMinuteSpinner.setEnabled(enabled); // 设置分钟选择器是否可用
mHourSpinner.setEnabled(enabled); // 设置小时选择器是否可用
mAmPmSpinner.setEnabled(enabled); // 设置上午/下午选择器是否可用
mIsEnabled = enabled; // 更新状态
}
@Override
public boolean isEnabled() {
return mIsEnabled;
}
/**
* Get the current date in millis
*
* @return the current date in millis
*/
public long getCurrentDateInTimeMillis() { //获取当前日期的时间戳
return mDate.getTimeInMillis();
}
/**
* Set the current date
*
* @param date The current date in millis
*/
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));
}
/**
* Set the current date
*
* @param year The current year
* @param month The current month
* @param dayOfMonth The current dayOfMonth
* @param hourOfDay The current hourOfDay
* @param minute The current minute
*/
public void setCurrentDate(int year, int month,
int dayOfMonth, int hourOfDay, int minute) { //设置当前日期
setCurrentYear(year); //设置当前年份
setCurrentMonth(month); //设置当前月份
setCurrentDay(dayOfMonth); //设置当前日期
setCurrentHour(hourOfDay); //设置当前小时
setCurrentMinute(minute); //设置当前分钟
}
/**
* Get current year
*
* @return The current year
*/
public int getCurrentYear() { //获取当前年份
return mDate.get(Calendar.YEAR);
}
/**
* Set current year
*
* @param year The current year
*/
public void setCurrentYear(int year) { //设置当前年份
if (!mInitialising && year == getCurrentYear()) { //如果初始化完成且当前年份和传入年份相同,则直接返回
return;
}
mDate.set(Calendar.YEAR, year); //设置当前年份
updateDateControl(); //更新日期控件
onDateTimeChanged(); //日期改变时调用
}
/**
* Get current month in the year
*
* @return The current month in the year
*/
public int getCurrentMonth() { //获取当前月份
return mDate.get(Calendar.MONTH);
}
/**
* Set current month in the year
*
* @param month The month in the year
*/
public void setCurrentMonth(int month) { //设置当前月份
if (!mInitialising && month == getCurrentMonth()) {
return;
}
mDate.set(Calendar.MONTH, month);
updateDateControl();
onDateTimeChanged();
}
/**
* Get current day of the month
*
* @return The day of the month
*/
public int getCurrentDay() { //获取当前日期
return mDate.get(Calendar.DAY_OF_MONTH);
}
/**
* Set current day of the month
*
* @param dayOfMonth The day of the month
*/
public void setCurrentDay(int dayOfMonth) { //设置当前日期
if (!mInitialising && dayOfMonth == getCurrentDay()) {
return;
}
mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateDateControl();
onDateTimeChanged();
}
/**
* Get current hour in 24 hour mode, in the range (0~23)
* @return The current hour in 24 hour mode
*/
public int getCurrentHourOfDay() { //获取当前小时
return mDate.get(Calendar.HOUR_OF_DAY);
}
private int getCurrentHour() {
if (mIs24HourView){ // 24小时模式
return getCurrentHourOfDay();
} else { // 12小时模式
int hour = getCurrentHourOfDay();
if (hour > HOURS_IN_HALF_DAY) { // 当前小时大于12小时返回当前小时减去12小时
return hour - HOURS_IN_HALF_DAY;
} else { // 当前小时小于等于12小时返回当前小时
return hour == 0 ? HOURS_IN_HALF_DAY : hour;
}
}
}
/**
* Set current hour in 24 hour mode, in the range (0~23)
*
* @param hourOfDay
*/
public void setCurrentHour(int hourOfDay) { //设置当前小时
if (!mInitialising && hourOfDay == getCurrentHourOfDay()) { //如果初始化完成且当前小时和传入的参数相等,则直接返回
return;
}
mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); //设置当前小时
if (!mIs24HourView) { //如果不是24小时制
if (hourOfDay >= HOURS_IN_HALF_DAY) { //如果传入的参数大于等于12
mIsAm = false; //设置AM为false
if (hourOfDay > HOURS_IN_HALF_DAY) { //如果传入的参数大于12
hourOfDay -= HOURS_IN_HALF_DAY; //减去12
}
} else {
mIsAm = true; //设置AM为true
if (hourOfDay == 0) { //如果传入的参数等于0
hourOfDay = HOURS_IN_HALF_DAY; //设置为12
}
}
updateAmPmControl(); //更新AM/PM控制
}
mHourSpinner.setValue(hourOfDay); //设置小时值
onDateTimeChanged(); //日期改变时调用
}
/**
* Get currentMinute
*
* @return The Current Minute
*/
public int getCurrentMinute() { //获取当前分钟
return mDate.get(Calendar.MINUTE);
}
/**
* Set current minute
*/
public void setCurrentMinute(int minute) { //设置当前分钟
if (!mInitialising && minute == getCurrentMinute()) { //如果初始化未完成,且分钟数相同,则返回
return;
}
mMinuteSpinner.setValue(minute); //设置分钟数
mDate.set(Calendar.MINUTE, minute); //设置日期
onDateTimeChanged(); //更新时间
}
/**
* @return true if this is in 24 hour view else false.
*/
public boolean is24HourView () { //获取是否是24小时视图
return mIs24HourView;
}
/**
* Set whether in 24 hour or AM/PM mode.
*
* @param is24HourView True for 24 hour mode. False for AM/PM mode.
*/
public void set24HourView(boolean is24HourView) { //设置24小时视图
if (mIs24HourView == is24HourView) {
return;
}
mIs24HourView = is24HourView;
mAmPmSpinner.setVisibility(is24HourView ? View.GONE : View.VISIBLE); //设置时间控制条的可见性
int hour = getCurrentHourOfDay(); //获取当前的小时
updateHourControl(); //更新小时控制条
setCurrentHour(hour); //设置当前的小时
updateAmPmControl(); //更新上午/下午控制条
}
private void updateDateControl() {
Calendar cal = Calendar.getInstance(); // 获取当前时间
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1); // 设置当前时间所在的星期
mDateSpinner.setDisplayedValues(null); // 设置显示的值
for (int i = 0; i < DAYS_IN_ALL_WEEK; ++i) { // 遍历所有的星期
cal.add(Calendar.DAY_OF_YEAR, 1);
mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal);
}
mDateSpinner.setDisplayedValues(mDateDisplayValues); // 设置显示的值
mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); // 设置当前时间所在的星期
mDateSpinner.invalidate();
}
private void updateAmPmControl() {
if (mIs24HourView) { // 如果24小时视图是可见的则隐藏AM/PM控制
mAmPmSpinner.setVisibility(View.GONE);
} else {
int index = mIsAm ? Calendar.AM : Calendar.PM; // 否则如果当前是AM则设置索引为Calendar.AM否则设置为Calendar.PM
mAmPmSpinner.setValue(index);
mAmPmSpinner.setVisibility(View.VISIBLE);
}
}
private void updateHourControl() {
if (mIs24HourView) { // 根据mIs24HourView的值来更新mHourSpinner的值
mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW);
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW);
} else {
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
*/
public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) { //设置日期时间改变监听器
mOnDateTimeChangedListener = callback;
}
private void onDateTimeChanged() {
if (mOnDateTimeChangedListener != null) { // 当日期时间改变时调用
mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(),
getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute());
}
}
}

@ -0,0 +1,101 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.ui;
import java.util.Calendar;
import net.micode.notes.R;
import net.micode.notes.ui.DateTimePicker;
import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener;
import android.app.AlertDialog;
import android.content.Context;
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 {
// 创建一个Calendar实例
private Calendar mDate = Calendar.getInstance();
// 是否是24小时制
private boolean mIs24HourView;
// 设置时间监听器
private OnDateTimeSetListener mOnDateTimeSetListener;
// 创建一个DateTimePicker实例
private DateTimePicker mDateTimePicker;
// 定义一个接口,用于设置时间
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) {
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);
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 =
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));
}
// 点击事件
public void onClick(DialogInterface arg0, int arg1) {
if (mOnDateTimeSetListener != null) {
mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis());
}
}
}

@ -0,0 +1,79 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.ui;
import android.content.Context;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;
import net.micode.notes.R;
public class DropdownMenu {
// 声明一个Button变量
private Button mButton;
// 声明一个PopupMenu变量
private PopupMenu mPopupMenu;
// 声明一个Menu变量
private Menu mMenu;
// 构造函数传入上下文、Button和菜单ID
public DropdownMenu(Context context, Button button, int menuId) {
// 将传入的Button赋值给mButton
mButton = button;
// 为mButton设置背景资源
mButton.setBackgroundResource(R.drawable.dropdown_icon);
// 创建一个PopupMenu传入上下文和mButton
mPopupMenu = new PopupMenu(context, mButton);
// 获取mPopupMenu的Menu
mMenu = mPopupMenu.getMenu();
// 为mMenu设置菜单ID
mPopupMenu.getMenuInflater().inflate(menuId, mMenu);
// 为mButton设置点击事件
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// 显示mPopupMenu
mPopupMenu.show();
}
});
}
// 设置点击事件
public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) {
// 如果mPopupMenu不为空
if (mPopupMenu != null) {
// 为mPopupMenu设置点击事件
mPopupMenu.setOnMenuItemClickListener(listener);
}
}
// 查找菜单项
public MenuItem findItem(int id) {
// 返回mMenu中id对应的菜单项
return mMenu.findItem(id);
}
// 设置标题
public void setTitle(CharSequence title) {
// 设置mButton的文本
mButton.setText(title);
}
}

@ -0,0 +1,92 @@
/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.micode.notes.ui;
import android.content.Context;
import android.database.Cursor;
import android.view.View;
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 {
// 定义查询列
public static final String [] PROJECTION = {
NoteColumns.ID,
NoteColumns.SNIPPET
};
// 定义查询列的索引
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) {
// 创建一个新的View
return new FolderListItem(context);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// 绑定View
if (view instanceof FolderListItem) {
// 获取文件夹名
String folderName = (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context
.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 = (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);
}
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.
Loading…
Cancel
Save