210340062刘瑞轩标注

lrx_branch
LiuRuiXuan 2 years ago
parent 6e3ccbfad2
commit a8a737de09

@ -0,0 +1,162 @@
/*
* 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;
/*
author:
2023-4-12
*/
public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
private long mNoteId;
private String mSnippet;
private static final int SNIPPET_PREW_MAX_LEN = 60;
MediaPlayer mPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);//创建实例
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//在锁定状态下唤醒屏幕。如果该标志被设置,则当 Activity 启动时,系统将唤醒设备并点亮屏幕。
| 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));//找到是否有对应的NoteId
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;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return;
}
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 变量
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
//获取当前系统中哪些音频流会受到静音模式的影响
int silentModeStreams = Settings.System.getInt(getContentResolver(),
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
//如果STREAM_ALARM受到影响那么就将音频流形式设置为silentModeStreams
if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) {
mPlayer.setAudioStreamType(silentModeStreams);
} else {
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
}
try {
mPlayer.setDataSource(this, url);
mPlayer.prepare();//于为音频播放做一些准备工作。具体来说,该方法会解析音频数据、分离音频轨道、获取音频格式信息等操作
mPlayer.setLooping(true);
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() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle(R.string.app_name);//设置对话框的标题
dialog.setMessage(mSnippet);//设置对话框的信息
dialog.setPositiveButton(R.string.notealert_ok, this);//设置确认按钮,在确认按钮按下后显示对话框
if (isScreenOn()) {
dialog.setNegativeButton(R.string.notealert_enter, this);//关闭对话框
}
dialog.show().setOnDismissListener(this);//执行相关的动作
}
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_NEGATIVE:
Intent intent = new Intent(this, NoteEditActivity.class);//新创建一个页面
intent.setAction(Intent.ACTION_VIEW);//显示页面
intent.putExtra(Intent.EXTRA_UID, mNoteId);//放入对应的数据库中
startActivity(intent);//运行该页面
break;
default:
break;
}
}
public void onDismiss(DialogInterface dialog) {
stopAlarmSound();//关闭闹钟铃声
finish();//该页面结束
}
private void stopAlarmSound() {
if (mPlayer != null) {//如果该播放器存在
mPlayer.stop();//停下
mPlayer.release();//释放资源
mPlayer = null;
}
}
}

@ -0,0 +1,70 @@
/*
* 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;
/*
Author:
Data:2023-4-12
*/
public class AlarmInitReceiver extends BroadcastReceiver {
private static final String [] PROJECTION = new String [] {
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,
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);//获取当前数据的日期
Intent sender = new Intent(context, AlarmReceiver.class);//获取一个新的页面
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);
alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent);//采用系统实时时钟RTC闹钟
//当闹钟到达alertDate时唤醒设备保证不会在睡眠模式错过闹钟第二个参数是闹钟的触发时间第三个就是指定谁到时候就会
//被触发
} while (c.moveToNext());//只要下一个数据存在的话
}
c.close();//关闭流文件
}
}
}

@ -0,0 +1,33 @@
/*
* 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;
/*
Author:
Data:2023/4/12
*/
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
intent.setClass(context, AlarmAlertActivity.class);//由当前页面跳转到对应界面
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//该标记表示在新任务栈中启动 Activity当它不在前台的时候保证其可以在后台显示
context.startActivity(intent);//启动对应的活动
}
}

@ -0,0 +1,489 @@
/*
* 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;
/*
Author:
Data:2023/4/12
*/
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() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {//更改日期
mDate.add(Calendar.DAY_OF_YEAR, newVal - oldVal);
updateDateControl();
onDateTimeChanged();
}
};//当用户更改值之后改变便签的修改日期
private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {//各自的参数代表被改变值得NumberPicker对象旧值新值
boolean isDateChanged = false;//用户是否改变值
Calendar cal = Calendar.getInstance();//获取当前的时间
if (!mIs24HourView) {//不是用的24小时制度
if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) {//是下午旧值是11新值是12代表到了下一天
cal.setTimeInMillis(mDate.getTimeInMillis());//将修改时间修改为当前的时间
cal.add(Calendar.DAY_OF_YEAR, 1);//过了一天将日期加1
isDateChanged = true;
} else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) {//如果当前是上午,并且
//旧值是12新值是11那么就代表回到了上一天
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 ||
oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) {//只要之前是11现在是12或者是之前是12现在是11AM和PM都会发生改变取反
mIsAm = !mIsAm;
updateAmPmControl();//更新限制
}
} else {
if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) {//如果当前时间比之前时间早,代表已经过了一天了
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, 1);
isDateChanged = true;
} else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) {//如果当前时间比之前时间晚代表是同一天
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) {//如果新的是最大的值,旧的是最小值,那么代表我们是往上调整的,那么小时减小
offset -= 1;
}
if (offset != 0) {//如果跨越边界了
mDate.add(Calendar.HOUR_OF_DAY, offset);//日期进行相应的改变
mHourSpinner.setValue(getCurrentHour());//获取当前的时间
updateDateControl();//更新限制
int newHour = getCurrentHourOfDay();//更新小时
if (newHour >= HOURS_IN_HALF_DAY) {//判断是上午还是下午
mIsAm = false;//不是上午
updateAmPmControl();//更新限制
} else {
mIsAm = true;//是上午
updateAmPmControl();
}
}
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);//如果是下午变成上午那么需要减去12小时
} else {
mDate.add(Calendar.HOUR_OF_DAY, HOURS_IN_HALF_DAY);//如果是上午变成下午那么需要加上12小时
}
updateAmPmControl();
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) {
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);//将小时、分钟和日期、在上午还是下午填充到这个文件中
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);//设置按下更新的间隔是100ms
mMinuteSpinner.setOnValueChangedListener(mOnMinuteChangedListener);//设置分钟监听器
String[] stringsForAmPm = new DateFormatSymbols().getAmPmStrings();//获取当前设备上的AM/PM字符串数组第一个元素为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);//设置上午下午监听器
// update controls to initial state
updateDateControl();//更新限制
updateHourControl();
updateAmPmControl();
set24HourView(is24HourView);
// set to current time
setCurrentDate(date);
setEnabled(isEnabled());
// set the content descriptions
mInitialising = false;
}
@Override
public void setEnabled(boolean enabled) {//用来设置组件显示出来
if (mIsEnabled == enabled) {//如果相同则不用修改
return;
}
super.setEnabled(enabled);//设置可行
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 {
int hour = getCurrentHourOfDay();//获取小时
if (hour > HOURS_IN_HALF_DAY) {//如果大于12应该减去12
return hour - HOURS_IN_HALF_DAY;
} else {
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) {
mIsAm = false;//代表是下午
if (hourOfDay > HOURS_IN_HALF_DAY) {//如果大于12
hourOfDay -= HOURS_IN_HALF_DAY;
}
} else {
mIsAm = true;//时上午
if (hourOfDay == 0) {
hourOfDay = HOURS_IN_HALF_DAY;//代表到达了最后
}
}
updateAmPmControl();
}
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 () {
return mIs24HourView;
}//返回是否是24小时制
/**
* 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) {
if (mIs24HourView == is24HourView) {//如果是24小时制就无需更改
return;
}
mIs24HourView = is24HourView;//更改为24小时制度
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);//清空mDateSpinner显示的数据
for (int i = 0; i < DAYS_IN_ALL_WEEK; ++i) {
cal.add(Calendar.DAY_OF_YEAR, 1);//将当前的cal的最后一个数据加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小时制
mAmPmSpinner.setVisibility(View.GONE);//上午下午不显示
} else {
int index = mIsAm ? Calendar.AM : Calendar.PM;//显示是上午还是下午
mAmPmSpinner.setValue(index);//显示对应的内容
mAmPmSpinner.setVisibility(View.VISIBLE);//可见
}
}
private void updateHourControl() {
if (mIs24HourView) {//如果是24小时制
mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW);//显示24小时最小值
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW);//显示24小时最大值
} else {
mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW);//显示12小时最小值
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW);//显示12小时最大值
}
}
/**
* 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,90 @@
/*
* 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 {
private Calendar mDate = Calendar.getInstance();
private boolean mIs24HourView;
private OnDateTimeSetListener mOnDateTimeSetListener;
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);//设置s为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()));//根据24小时制或者是12小时进行设置
updateTitle(mDate.getTimeInMillis());//更新题目
}
public void set24HourView(boolean is24HourView) {
mIs24HourView = is24HourView;
}//设置为24小时页面
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;//是否按照24小时制显示
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,61 @@
/*
* 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 {
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);//设置背景资源,改变对应的背景图片
mPopupMenu = new PopupMenu(context, mButton);//显示菜单
mMenu = mPopupMenu.getMenu();
mPopupMenu.getMenuInflater().inflate(menuId, mMenu);//填充菜单
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mPopupMenu.show();
}//显示对应的菜单
});
}
public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) {
if (mPopupMenu != null) {
mPopupMenu.setOnMenuItemClickListener(listener);
}
}
public MenuItem findItem(int id) {
return mMenu.findItem(id);
}
public void setTitle(CharSequence title) {
mButton.setText(title);
}
}

@ -0,0 +1,84 @@
/*
* 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 {
//CursorAdapter是Cursor和ListView的接口
//FoldersListAdapter继承了CursorAdapter的类
//主要作用是便签数据库和用户的交互
//这里就是用folder文件夹的形式展现给用户
public static final String [] PROJECTION = {
NoteColumns.ID,
NoteColumns.SNIPPET
};//调用数据库中便签的ID和片段
public static final int ID_COLUMN = 0;
public static final int NAME_COLUMN = 1;
public FoldersListAdapter(Context context, Cursor c) {
super(context, c);
// TODO Auto-generated constructor stub
}//数据库操作
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return new FolderListItem(context);
}//创建一个文件夹,对于各文件夹中子标签的初始化
@Override
public void bindView(View view, Context context, Cursor cursor) {
if (view instanceof FolderListItem) {//FolderListItem是显示子图如果view是该类的实例那么就去cursor中获取文件夹的名称并将其绑定到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) 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);//根据布局文件的名字等信息将其找出来
}
public void bind(String name) {
mName.setText(name);
}
}
}
Loading…
Cancel
Save