|
|
|
@ -0,0 +1,420 @@
|
|
|
|
|
package com.example.sleep;
|
|
|
|
|
|
|
|
|
|
import android.app.Activity;
|
|
|
|
|
import android.app.Dialog;
|
|
|
|
|
import android.content.Intent;
|
|
|
|
|
import android.graphics.Color;
|
|
|
|
|
import android.os.Bundle;
|
|
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
|
import android.support.design.widget.CoordinatorLayout;
|
|
|
|
|
import android.support.v4.view.ViewPager;
|
|
|
|
|
import android.view.Gravity;
|
|
|
|
|
import android.view.KeyEvent;
|
|
|
|
|
import android.view.View;
|
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
|
import android.view.Window;
|
|
|
|
|
import android.widget.Button;
|
|
|
|
|
import android.widget.FrameLayout;
|
|
|
|
|
import android.widget.TextView;
|
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
|
|
import com.bigkoo.pickerview.builder.TimePickerBuilder;
|
|
|
|
|
import com.bigkoo.pickerview.listener.OnTimeSelectListener;
|
|
|
|
|
import com.bigkoo.pickerview.view.TimePickerView;
|
|
|
|
|
import com.example.sleep.calendarInfo.CustomDayView;
|
|
|
|
|
import com.example.sleep.database.GetRecord;
|
|
|
|
|
import com.example.sleep.service.GoSleepService;
|
|
|
|
|
import com.ldf.calendar.component.CalendarAttr;
|
|
|
|
|
import com.ldf.calendar.component.CalendarViewAdapter;
|
|
|
|
|
import com.ldf.calendar.interf.OnSelectDateListener;
|
|
|
|
|
import com.ldf.calendar.model.CalendarDate;
|
|
|
|
|
import com.ldf.calendar.view.MonthPager;
|
|
|
|
|
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Locale;
|
|
|
|
|
|
|
|
|
|
import static com.example.sleep.database.GetRecord.getRecord;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 睡眠记录页面
|
|
|
|
|
*/
|
|
|
|
|
public class CalendarPage extends Activity {
|
|
|
|
|
|
|
|
|
|
Button btn_left;
|
|
|
|
|
Button btn_right;
|
|
|
|
|
// 获取记录的对象
|
|
|
|
|
GetRecord mGetRecord;
|
|
|
|
|
// 记录数据的二维数组,用于标记每天是否有记录
|
|
|
|
|
boolean[][] recordData;
|
|
|
|
|
// 时间选择视图
|
|
|
|
|
private TimePickerView pvTime;
|
|
|
|
|
// 退出时间,用于控制双击返回键退出应用
|
|
|
|
|
private long exitTime = 0;
|
|
|
|
|
|
|
|
|
|
// 日历属性
|
|
|
|
|
TextView tvYear;
|
|
|
|
|
TextView tvMonth;
|
|
|
|
|
CoordinatorLayout content;
|
|
|
|
|
MonthPager monthPager;
|
|
|
|
|
|
|
|
|
|
// 当前日历视图的集合
|
|
|
|
|
private ArrayList<com.ldf.calendar.view.Calendar> currentCalendars = new ArrayList<>();
|
|
|
|
|
// 日历视图适配器
|
|
|
|
|
private CalendarViewAdapter calendarAdapter;
|
|
|
|
|
// 日期选择监听器
|
|
|
|
|
private OnSelectDateListener onSelectDateListener;
|
|
|
|
|
// 当前日期
|
|
|
|
|
private CalendarDate currentDate;
|
|
|
|
|
// 是否已初始化标志
|
|
|
|
|
private boolean initiated = false;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
|
// 设置布局文件
|
|
|
|
|
setContentView(R.layout.calendar);
|
|
|
|
|
// 获取记录对象
|
|
|
|
|
mGetRecord = getRecord();
|
|
|
|
|
// 获取日历视图
|
|
|
|
|
monthPager = findViewById(R.id.calendar_view);
|
|
|
|
|
// 初始化记录数据数组
|
|
|
|
|
recordData = new boolean[13][];
|
|
|
|
|
// 初始化视图和时间选择器
|
|
|
|
|
initView();
|
|
|
|
|
initTimePicker();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initView() {
|
|
|
|
|
// 初始化记录数据,并根据每个月的天数查询是否有记录
|
|
|
|
|
int dayNum;
|
|
|
|
|
for (int m = 1; m <= 12; ++m) {
|
|
|
|
|
if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {
|
|
|
|
|
dayNum = 31;
|
|
|
|
|
} else if (m == 2) {
|
|
|
|
|
dayNum = 28;
|
|
|
|
|
} else {
|
|
|
|
|
dayNum = 30;
|
|
|
|
|
}
|
|
|
|
|
recordData[m] = mGetRecord.queryByMonth(Integer.toString(m), dayNum);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化视图元素
|
|
|
|
|
btn_left = findViewById(R.id.left);
|
|
|
|
|
btn_right = findViewById(R.id.right);
|
|
|
|
|
content = findViewById(R.id.content);
|
|
|
|
|
tvYear = findViewById(R.id.show_year_view);
|
|
|
|
|
tvMonth = findViewById(R.id.show_month_view);
|
|
|
|
|
// 初始化当前日期
|
|
|
|
|
initCurrentDate();
|
|
|
|
|
// 初始化日历视图
|
|
|
|
|
initCalendarView();
|
|
|
|
|
// 初始化工具栏点击监听
|
|
|
|
|
initToolbarClickListener();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化currentDate
|
|
|
|
|
*/
|
|
|
|
|
private void initCurrentDate() {
|
|
|
|
|
currentDate = new CalendarDate();
|
|
|
|
|
// 设置年份
|
|
|
|
|
tvYear.setText(String.format(getResources().getString(R.string.year), currentDate.getYear()));
|
|
|
|
|
// 设置月份
|
|
|
|
|
tvMonth.setText(String.format(getResources().getString(R.string.month), currentDate.getMonth()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化CustomDayView,并作为CalendarViewAdapter的参数传入
|
|
|
|
|
*/
|
|
|
|
|
private void initCalendarView() {
|
|
|
|
|
// 初始化日历点击事件监听
|
|
|
|
|
initListener();
|
|
|
|
|
// 创建自定义日期视图
|
|
|
|
|
CustomDayView customDayView = new CustomDayView(this, R.layout.custom_day);
|
|
|
|
|
calendarAdapter = new CalendarViewAdapter(
|
|
|
|
|
this,
|
|
|
|
|
onSelectDateListener,
|
|
|
|
|
CalendarAttr.CalendarType.MONTH,
|
|
|
|
|
CalendarAttr.WeekArrayType.Monday,
|
|
|
|
|
customDayView);// 创建日历视图适配器
|
|
|
|
|
calendarAdapter.setOnCalendarTypeChangedListener(new CalendarViewAdapter.OnCalendarTypeChanged() {
|
|
|
|
|
@Override
|
|
|
|
|
// 日历类型改变时的操作
|
|
|
|
|
public void onCalendarTypeChanged(CalendarAttr.CalendarType type) {
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 初始化日历标记数据
|
|
|
|
|
initMarkData();
|
|
|
|
|
// 初始化月份切换功能
|
|
|
|
|
initMonthPager();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//使用此方法回调日历点击事件
|
|
|
|
|
private void initListener() {
|
|
|
|
|
onSelectDateListener = new OnSelectDateListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onSelectDate(CalendarDate date) {
|
|
|
|
|
// 刷新点击日期的操作
|
|
|
|
|
refreshClickDate(date);
|
|
|
|
|
Intent i = new Intent();
|
|
|
|
|
int d;
|
|
|
|
|
d = date.getDay();
|
|
|
|
|
if (recordData[date.month][d]) {
|
|
|
|
|
// 跳转到记录页面
|
|
|
|
|
i.setClass(CalendarPage.this, Record.class);
|
|
|
|
|
// 将日期信息传递到记录页面
|
|
|
|
|
i.putExtra("date", date.month + "-" + date.day);
|
|
|
|
|
CalendarPage.this.startActivity(i);
|
|
|
|
|
} else {
|
|
|
|
|
// 提示没有记录信息
|
|
|
|
|
Toast.makeText(CalendarPage.this, "没有记录信息", Toast.LENGTH_SHORT).show();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onSelectOtherMonth(int offset) {
|
|
|
|
|
//偏移量 -1表示上一个月 , 1表示下一个月
|
|
|
|
|
monthPager.selectOtherMonth(offset);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//使用此方法初始化日历标记数据
|
|
|
|
|
private void initMarkData() {
|
|
|
|
|
HashMap<String, String> markData = new HashMap<>();
|
|
|
|
|
//1表示红点,0表示灰点,只在日历上标注出灰点表示没有打卡的日期
|
|
|
|
|
String s;
|
|
|
|
|
int dayNum;
|
|
|
|
|
for (int m = 1; m <= 12; m++) {
|
|
|
|
|
if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) {
|
|
|
|
|
dayNum = 31;
|
|
|
|
|
} else if (m == 2) {
|
|
|
|
|
dayNum = 28;
|
|
|
|
|
} else {
|
|
|
|
|
dayNum = 30;
|
|
|
|
|
}
|
|
|
|
|
for (int i = 1; i <= dayNum; i++) {
|
|
|
|
|
if (recordData[m][i]) {
|
|
|
|
|
s = "2019-" + m + "-" + i;
|
|
|
|
|
// 标记为红点
|
|
|
|
|
markData.put(s, "1");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 设置日历标记数据
|
|
|
|
|
calendarAdapter.setMarkData(markData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化monthPager,MonthPager继承自ViewPager
|
|
|
|
|
*/
|
|
|
|
|
private void initMonthPager() {
|
|
|
|
|
// 设置适配器
|
|
|
|
|
monthPager.setAdapter(calendarAdapter);
|
|
|
|
|
// 设置当前选中项为当天
|
|
|
|
|
monthPager.setCurrentItem(MonthPager.CURRENT_DAY_INDEX);
|
|
|
|
|
// 设置页面切换动画
|
|
|
|
|
monthPager.setPageTransformer(false, new ViewPager.PageTransformer() {
|
|
|
|
|
@Override
|
|
|
|
|
public void transformPage(@NonNull View page, float position) {
|
|
|
|
|
position = (float) Math.sqrt(1 - Math.abs(position));
|
|
|
|
|
page.setAlpha(position);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 添加页面变化监听器
|
|
|
|
|
monthPager.addOnPageChangeListener(new MonthPager.OnPageChangeListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
|
|
|
|
// 页面滚动时的处理
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onPageSelected(int position) {
|
|
|
|
|
// 页面选中时的处理
|
|
|
|
|
currentCalendars = calendarAdapter.getPagers();
|
|
|
|
|
if (currentCalendars.get(position % currentCalendars.size()) != null) {
|
|
|
|
|
CalendarDate date = currentCalendars.get(position % currentCalendars.size()).getSeedDate();
|
|
|
|
|
currentDate = date;
|
|
|
|
|
tvYear.setText(String.format(getResources().getString(R.string.year), date.getYear()));
|
|
|
|
|
tvMonth.setText(String.format(getResources().getString(R.string.month), date.getMonth()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public void onPageScrollStateChanged(int state) {
|
|
|
|
|
// 页面滚动状态改变时的处理
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化对应功能的listener
|
|
|
|
|
*/
|
|
|
|
|
private void initToolbarClickListener() {
|
|
|
|
|
// 左按钮点击事件
|
|
|
|
|
btn_left.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(View view) {
|
|
|
|
|
// 切换到上一个月
|
|
|
|
|
monthPager.setCurrentItem(monthPager.getCurrentPosition() - 1);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
// 右按钮点击事件
|
|
|
|
|
btn_right.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onClick(View view) {
|
|
|
|
|
// 切换到下一个月
|
|
|
|
|
monthPager.setCurrentItem(monthPager.getCurrentPosition() + 1);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化时间选择器
|
|
|
|
|
*/
|
|
|
|
|
private void initTimePicker() {
|
|
|
|
|
// 创建时间选择器
|
|
|
|
|
pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() {
|
|
|
|
|
@Override
|
|
|
|
|
// 选中时间的回调处理
|
|
|
|
|
public void onTimeSelect(Date date, View v) {
|
|
|
|
|
Toast.makeText(CalendarPage.this, "设置成功!", Toast.LENGTH_SHORT).show();
|
|
|
|
|
mGetRecord.updateRemind(getTime(date));
|
|
|
|
|
stopGoSleepService();
|
|
|
|
|
startGoSleepService();
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.setType(new boolean[]{false, false, false, true, true, false})// 默认全部显示
|
|
|
|
|
.setCancelText("取消")//取消按钮文字
|
|
|
|
|
.setSubmitText("确认")//确认按钮文字
|
|
|
|
|
.setTitleSize(20)//标题文字大小
|
|
|
|
|
.setTitleText("选择提醒时间")//标题文字
|
|
|
|
|
.setOutSideCancelable(false)//点击屏幕,点在控件外部范围时,是否取消显示
|
|
|
|
|
.isCyclic(true)//是否循环滚动
|
|
|
|
|
.setTitleColor(Color.BLACK)//标题文字颜色
|
|
|
|
|
.setSubmitColor(Color.BLUE)//确定按钮文字颜色
|
|
|
|
|
.setCancelColor(Color.BLUE)//取消按钮文字颜色
|
|
|
|
|
//.setTitleBgColor(0xFF666666)//标题背景颜色 Night mode
|
|
|
|
|
//.setBgColor(0xFF333333)//滚轮背景颜色 Night mode
|
|
|
|
|
.setLabel("年", "月", "日", "时", "分", "秒")//默认设置为年月日时分秒
|
|
|
|
|
.isCenterLabel(false) //是否只显示中间选中项的label文字,false则每项item全部都带有label。
|
|
|
|
|
.isDialog(true)//是否显示为对话框样式
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
// 设置时间选择器对话框样式
|
|
|
|
|
Dialog mDialog = pvTime.getDialog();
|
|
|
|
|
if (mDialog != null) {
|
|
|
|
|
// 设置对话框在底部显示
|
|
|
|
|
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
|
|
|
|
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
|
|
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
|
|
|
|
Gravity.BOTTOM);
|
|
|
|
|
|
|
|
|
|
params.leftMargin = 0;
|
|
|
|
|
params.rightMargin = 0;
|
|
|
|
|
pvTime.getDialogContainerLayout().setLayoutParams(params);
|
|
|
|
|
|
|
|
|
|
Window dialogWindow = mDialog.getWindow();
|
|
|
|
|
if (dialogWindow != null) {
|
|
|
|
|
//修改动画样式
|
|
|
|
|
dialogWindow.setWindowAnimations(com.bigkoo.pickerview.R.style.picker_view_slide_anim);
|
|
|
|
|
dialogWindow.setGravity(Gravity.BOTTOM);
|
|
|
|
|
dialogWindow.setDimAmount(0.1f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void refreshClickDate(CalendarDate date) {
|
|
|
|
|
currentDate = date;
|
|
|
|
|
tvYear.setText(String.format(getResources().getString(R.string.year), date.getYear()));
|
|
|
|
|
tvMonth.setText(String.format(getResources().getString(R.string.month), date.getMonth()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 点击提醒按钮
|
|
|
|
|
*/
|
|
|
|
|
public void onClickRemind(View v) {
|
|
|
|
|
if (pvTime != null) {
|
|
|
|
|
// 弹出时间选择器,传递参数过去,回调的时候则可以绑定此view
|
|
|
|
|
pvTime.show(v);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 点击睡眠按钮
|
|
|
|
|
*/
|
|
|
|
|
public void ClickSleep(View v) {
|
|
|
|
|
// 跳转到MainActivity并关闭当前页面
|
|
|
|
|
Intent i = new Intent();
|
|
|
|
|
i.setClass(CalendarPage.this, MainActivity.class);
|
|
|
|
|
CalendarPage.this.startActivity(i);
|
|
|
|
|
CalendarPage.this.finish();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
// 当窗口焦点状态改变时调用,用于在应用获得焦点且未初始化时更新日历视图
|
|
|
|
|
public void onWindowFocusChanged(boolean hasFocus) {
|
|
|
|
|
super.onWindowFocusChanged(hasFocus);
|
|
|
|
|
if (hasFocus && !initiated) {
|
|
|
|
|
// 获取当天日期
|
|
|
|
|
CalendarDate today = new CalendarDate();
|
|
|
|
|
// 通知日历视图数据改变
|
|
|
|
|
calendarAdapter.notifyDataChanged(today);
|
|
|
|
|
// 设置初始化标志为true
|
|
|
|
|
initiated = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
// 按键按下事件监听,用于实现双击返回键退出应用
|
|
|
|
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
|
|
|
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
|
|
|
|
|
if (System.currentTimeMillis() - exitTime > 2000) {
|
|
|
|
|
// 判断两次点击返回键的时间间隔
|
|
|
|
|
// 提示再次点击退出
|
|
|
|
|
Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
|
|
|
|
|
// 更新退出时间
|
|
|
|
|
exitTime = System.currentTimeMillis();
|
|
|
|
|
} else {
|
|
|
|
|
// 关闭当前Activity
|
|
|
|
|
finish();
|
|
|
|
|
// 退出应用
|
|
|
|
|
System.exit(0);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return super.onKeyDown(keyCode, event);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取时间字符串
|
|
|
|
|
*/
|
|
|
|
|
private String getTime(Date date) {
|
|
|
|
|
return new SimpleDateFormat("HH:mm", Locale.getDefault()).format(date);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 启动后台服务
|
|
|
|
|
*/
|
|
|
|
|
public void startGoSleepService() {
|
|
|
|
|
Intent ifSleepIntent = new Intent(this, GoSleepService.class);
|
|
|
|
|
this.startService(ifSleepIntent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 停止后台服务
|
|
|
|
|
*/
|
|
|
|
|
public void stopGoSleepService() {
|
|
|
|
|
Intent ifSleepIntent = new Intent(this, GoSleepService.class);
|
|
|
|
|
this.stopService(ifSleepIntent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 销毁Activity
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public void onDestroy() {
|
|
|
|
|
super.onDestroy();
|
|
|
|
|
}
|
|
|
|
|
}
|