从来都没有做过日历相关的UI,第一反应就是去找第三方的框架,找来找去发现都不太适合,不太好自定义,后来仔细看看,实现起来应该不难,整体采用recyclerview实现布局,关键在于数据的获取,后面想想只需要三个数据。
1.某年某月有多少天
2.某年某月第一天是星期几
3.当天日期 (当天以前日期不可点并设置背景为灰色)
实现如下:
/**
* 初始化数据
* @param type
*/
private void initData(int type) {
if(type==1){//当天日期
//当月的天数
int currentMonthDay = TimeUtil.getCurrentMonthDay();
//当月第一天日期
String firstDayOfMonth = TimeUtil.getFirstDayOfMonth(TimeUtil.dateFormatYMD);
//当月第一天的星期几
int dayOfWeekByDate = TimeUtil.getDayOfWeekByDate(firstDayOfMonth);
addList(dayOfWeekByDate,currentMonthDay,true);
}else {
//下个月
String nextMoth="";
if(TimeUtil.getCurrentMonth()<9){
nextMoth="0"+(TimeUtil.getCurrentMonth()+1);
}else {
nextMoth=""+(TimeUtil.getCurrentMonth()+1);
}
//下个月一号
String nextMothDay=TimeUtil.getCurrentYear()+"-"+nextMoth+"-01";
//获取下个月有多少天
int daysByYearMonth = TimeUtil.getDaysByYearMonth(TimeUtil.getCurrentYear(), TimeUtil.getCurrentMonth() + 1);
//获取下个月1号是星期几
int dayOfWeekByDate = TimeUtil.getDayOfWeekByDate(nextMothDay);
addList(dayOfWeekByDate,daysByYearMonth,false);
}
//计算行数 设置高度
int p=modelList.size()%7;
int line=0;
if(p==0){
line=modelList.size()/7;
}else {
line=modelList.size()/7+1;
}
ViewGroup.LayoutParams layoutParams = recyclerview.getLayoutParams();
layoutParams.height= Util.dip2px(40)*line;
recyclerview.setLayoutParams(layoutParams);
adapter.notifyDataSetChanged();
}
/**
*
* @param dayOfWeekByDate 星期几
* @param currentMonthDay 当月有多少天
* @param isCurrmoth 是不是当月的
*/
private void addList(int dayOfWeekByDate,int currentMonthDay,boolean isCurrmoth){
for(int i=0;i<dayOfWeekByDate;i++){
KalanderModel kalanderModel=new KalanderModel();
kalanderModel.viewType=MessageAdapter.KALENDAR_ITEM;
kalanderModel.isCanClickable=false;
modelList.add(kalanderModel);
}
for(int i=0;i<currentMonthDay;i++){
KalanderModel kalanderModel=new KalanderModel();
kalanderModel.viewType=MessageAdapter.KALENDAR_ITEM;
if(isCurrmoth){
int currDay=TimeUtil.getCurrentDay1();
if(i<currDay){
kalanderModel.isCanClickable=false;
}else {
kalanderModel.isCanClickable=true;
}
kalanderModel.mouth=TimeUtil.getCurrentMonth();
}else {
kalanderModel.isCanClickable=true;
kalanderModel.mouth=TimeUtil.getCurrentMonth()+1;
}
kalanderModel.year=TimeUtil.getCurrentYear();
kalanderModel.day=i+1;
modelList.add(kalanderModel);
}
}
/**
* 公司:杭州融科网络科技
* 刘宇飞 创建 on 2017/3/10.
* 描述:日历model
*/
public class KalanderModel extends BaseRecyclerModel {
public int year;
public int mouth;
public int day;
public boolean isCanClickable;
}
工具类:
/*
*
*/
package com.ikuaibaike.qishou.kuaibaike.utils;
import android.annotation.SuppressLint;
import android.text.TextUtils;
import android.text.format.Time;
import android.util.Log;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
/**
* 描述:日期处理类.
*/
@SuppressWarnings("all")
public class TimeUtil {
/**
* one day millisecond count
*/
public static final long ONE_DAY_MILLISECONDS = 1000 * 3600 * 24;
public static final long ONE_HOUR_MILLISECONDS = 1000 * 3600;
public static final long ONE_MIN_MILLISECONDS = 1000 * 60;
/**
* 时间日期格式化到年月日时分秒.
*/
public static String dateFormatYMDHMS = "yyyy-MM-dd HH:mm:ss";
public static String dateFormatYMDHMS_f = "yyyyMMddHHmmss";
public static String dateFormatMDHM = "MM-dd HH:mm";
public static String dateFormat = "yyyy-MM-dd HH:mm";
/**
* 时间日期格式化到年月日.
*/
public static String dateFormatYMD = "yyyy-MM-dd";
/**
* 时间日期格式化到年月日时分.中文显示
*/
public static String dateFormatYMDHMofChinese = "yyyy年MM月dd日 HH:mm";
/**
* 时间日期格式化到年月日.中文显示
*/
public static String dateFormatYMDofChinese = "yyyy年MM月dd日";
/**
* 时间日期格式化到月日.中文显示
*/
public static String dateFormatMDofChinese = "MM月dd日";
/**
* 时间日期格式化到月.中文显示
*/
public static String dateFormatMofChinese = "MM月";
/**
* 时间日期格式化到年月.
*/
public static String dateFormatYM = "yyyy-MM";
/**
* 时间日期格式化到年月日时分.
*/
public static String dateFormatYMDHM = "yyyy-MM-dd HH:mm";
/**
* 时间日期格式化到月日.
*/
public static String dateFormatMD = "MM/dd";
public static String dateFormatM_D = "MM-dd";
public static String dateFormatM = "MM月";
public static String dateFormatD = "dd";
public static String dateFormatM2 = "MM";
public static String dateFormatMDHMofChinese = "MM月dd日HH时mm分";
public static String dateFormatHMofChinese = "HH时mm分";
/**
* 时分秒.
*/
public static String dateFormatHMS = "HH:mm:ss";
/**
* 时分.
*/
public static String dateFormatHM = "HH:mm";
/**
* 上午/下午时分
*/
public static String dateFormatAHM = "aHH:mm";
public static String dateFormatYMDE = "yyyy/MM/dd E";
public static String dateFormatYMD2 = "yyyy/MM/dd";
private final static ThreadLocal<SimpleDateFormat> dateFormater = new ThreadLocal<SimpleDateFormat>() {
@SuppressLint("SimpleDateFormat")
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
@SuppressLint("SimpleDateFormat")
private final static ThreadLocal<SimpleDateFormat> dateFormater2 = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
private static Time t;
/**
* 时间戳转特定格式时间
*
* @param dataFormat
* @param timeStamp
* @return
*/
public static String formatData(String dataFormat, long timeStamp) {
if (timeStamp == 0) {
return "";
}
timeStamp = timeStamp * 1000;
SimpleDateFormat format = new SimpleDateFormat(dataFormat);
return format.format(new Date(timeStamp));
}
/**
* 将毫秒转换成秒
*
* @param time
* @return
*/
public static int convertToSecond(Long time) {
Date date = new Date();
date.setTime(time);
return date.getSeconds();
}
/**
* 描述:String类型的日期时间转化为Date类型.
*
* @param strDate String形式的日期时间
* @param format 格式化字符串,如:"yyyy-MM-dd HH:mm:ss"
* @return Date Date类型日期时间
*/
public static Date getDateByFormat(String strDate, String format) {
SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat(format);
Date date = null;
try {
date = mSimpleDateFormat.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
/**
* 描述:获取偏移之后的Date.
*
* @param date 日期时间
* @param calendarField Calendar属性,对应offset的值, 如(Calendar.DATE,表示+offset天,Calendar.HOUR_OF_DAY,表示+offset小时)
* @param offset 偏移(值大于0,表示+,值小于0,表示-)
* @return Date 偏移之后的日期时间
*/
public Date getDateByOffset(Date date, int calendarField, int offset) {
Calendar c = new GregorianCalendar();
try {
c.setTime(date);
c.add(calendarField, offset);
} catch (Exception e) {
e.printStackTrace();
}
return c.getTime();
}
/**
* 描述:获取指定日期时间的字符串(可偏移).
*
* @param strDate String形式的日期时间
* @param format 格式化字符串,如:"yyyy-MM-dd HH:mm:ss"
* @param calendarField Calendar属性,对应offset的值, 如(Calendar.DATE,表示+offset天,Calendar.HOUR_OF_DAY,表示+offset小时)
* @param offset 偏移(值大于0,表示+,值小于0,表示-)
* @return String String类型的日期时间
*/
public static String getStringByOffset(String strDate, String format, int calendarField, int offset) {
String mDateTime = null;
try {
Calendar c = new GregorianCalendar();
SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat(format);
c.setTime(mSimpleDateFormat.parse(strDate));
c.add(calendarField, offset);
mDateTime = mSimpleDateFormat.format(c.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
return mDateTime;
}
/**
* 描述:Date类型转化为String类型(可偏移).
*
* @param date the date
* @param format the format
* @param calendarField the calendar field
* @param offset the offset
* @return String String类型日期时间
*/
public static String getStringByOffset(Date date, String format, int calendarField, int offset) {
String strDate = null;
try {
Calendar c = new GregorianCalendar();
SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat(format);
c.setTime(date);
c.add(calendarField, offset);
strDate = mSimpleDateFormat.format(c.getTime());
} catch (Exception e) {
e.printStackTrace();
}
return strDate;
}
/**
* from yyyy-MM-dd HH:mm:ss to MM-dd HH:mm
*/
public static String formatDate(String before) {
String after;
try {
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
.parse(before);
after = new SimpleDateFormat("MM-dd HH:mm", Locale.getDefault()).format(date);
} catch (ParseException e) {
return before;
}
return after;
}
/**
* 描述:Date类型转化为String类型.
*
* @param date the date
* @param format the format
* @return String String类型日期时间
*/
public static String getStringByFormat(Date date, String format) {
SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat(format);
String strDate = null;
try {
strDate = mSimpleDateFormat.format(date);
} catch (Exception e) {
e.printStackTrace();
}
return strDate;
}
/**
* 描述:获取指定日期时间的字符串,用于导出想要的格式.
*
* @param strDate String形式的日期时间,必须为yyyy-MM-dd HH:mm:ss格式
* @param format 输出格式化字符串,如:"yyyy-MM-dd HH:mm:ss"
* @return String 转换后的String类型的日期时间
*/
public static String getStringByFormat(String strDate, String format) {
String mDateTime = null;
try {
Calendar c = new GregorianCalendar();
SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat(format);
c.setTime(mSimpleDateFormat.parse(strDate));
SimpleDateFormat mSimpleDateFormat2 = new SimpleDateFormat(format);
mDateTime = mSimpleDateFormat2.format(c.getTime());
} catch (Exception e) {
e.printStackTrace();
}
return mDateTime;
}
/**
* 描述:获取milliseconds表示的日期时间的字符串.
*
* @param format 格式化字符串,如:"yyyy-MM-dd HH:mm:ss"
* @return String 日期时间字符串
*/
public static String getStringByFormat(long milliseconds, String format) {
String thisDateTime = null;
try {
SimpleDateFormat mSimpleDateFormat = new SimpleDatnullnullnull