先看一下效果图

根据项目需求选择合适的控件
下面这张图就是根据第一个日历进行的改动

1.创建一个类LunarHelper(阴历)
class LunarHelper {
private final static int[] lunar_month_days = {1887, 0x1694, 0x16aa, 0x4ad5, 0xab6, 0xc4b7, 0x4ae, 0xa56, 0xb52a, 0x1d2a,
0xd54, 0x75aa, 0x156a, 0x1096d, 0x95c, 0x14ae, 0xaa4d, 0x1a4c, 0x1b2a, 0x8d55, 0xad4, 0x135a, 0x495d, 0x95c,
0xd49b, 0x149a, 0x1a4a, 0xbaa5, 0x16a8, 0x1ad4, 0x52da, 0x12b6, 0xe937, 0x92e, 0x1496, 0xb64b, 0xd4a, 0xda8,
0x95b5, 0x56c, 0x12ae, 0x492f, 0x92e, 0xcc96, 0x1a94, 0x1d4a, 0xada9, 0xb5a, 0x56c, 0x726e, 0x125c, 0xf92d,
0x192a, 0x1a94, 0xdb4a, 0x16aa, 0xad4, 0x955b, 0x4ba, 0x125a, 0x592b, 0x152a, 0xf695, 0xd94, 0x16aa, 0xaab5,
0x9b4, 0x14b6, 0x6a57, 0xa56, 0x1152a, 0x1d2a, 0xd54, 0xd5aa, 0x156a, 0x96c, 0x94ae, 0x14ae, 0xa4c, 0x7d26,
0x1b2a, 0xeb55, 0xad4, 0x12da, 0xa95d, 0x95a, 0x149a, 0x9a4d, 0x1a4a, 0x11aa5, 0x16a8, 0x16d4, 0xd2da,
0x12b6, 0x936, 0x9497, 0x1496, 0x1564b, 0xd4a, 0xda8, 0xd5b4, 0x156c, 0x12ae, 0xa92f, 0x92e, 0xc96, 0x6d4a,
0x1d4a, 0x10d65, 0xb58, 0x156c, 0xb26d, 0x125c, 0x192c, 0x9a95, 0x1a94, 0x1b4a, 0x4b55, 0xad4, 0xf55b,
0x4ba, 0x125a, 0xb92b, 0x152a, 0x1694, 0x96aa, 0x15aa, 0x12ab5, 0x974, 0x14b6, 0xca57, 0xa56, 0x1526,
0x8e95, 0xd54, 0x15aa, 0x49b5, 0x96c, 0xd4ae, 0x149c, 0x1a4c, 0xbd26, 0x1aa6, 0xb54, 0x6d6a, 0x12da,
0x1695d, 0x95a, 0x149a, 0xda4b, 0x1a4a, 0x1aa4, 0xbb54, 0x16b4, 0xada, 0x495b, 0x936, 0xf497, 0x1496,
0x154a, 0xb6a5, 0xda4, 0x15b4, 0x6ab6, 0x126e, 0x1092f, 0x92e, 0xc96, 0xcd4a, 0x1d4a, 0xd64, 0x956c, 0x155c,
0x125c, 0x792e, 0x192c, 0xfa95, 0x1a94, 0x1b4a, 0xab55, 0xad4, 0x14da, 0x8a5d, 0xa5a, 0x1152b, 0x152a,
0x1694, 0xd6aa, 0x15aa, 0xab4, 0x94ba, 0x14b6, 0xa56, 0x7527, 0xd26, 0xee53, 0xd54, 0x15aa, 0xa9b5, 0x96c,
0x14ae, 0x8a4e, 0x1a4c, 0x11d26, 0x1aa4, 0x1b54, 0xcd6a, 0xada, 0x95c, 0x949d, 0x149a, 0x1a2a, 0x5b25,
0x1aa4, 0xfb52, 0x16b4, 0xaba, 0xa95b, 0x936, 0x1496, 0x9a4b, 0x154a, 0x136a5, 0xda4, 0x15ac};
private final static int[] solar_1_1 = {1887, 0xec04c, 0xec23f, 0xec435, 0xec649, 0xec83e, 0xeca51, 0xecc46, 0xece3a,
0xed04d, 0xed242, 0xed436, 0xed64a, 0xed83f, 0xeda53, 0xedc48, 0xede3d, 0xee050, 0xee244, 0xee439, 0xee64d,
0xee842, 0xeea36, 0xeec4a, 0xeee3e, 0xef052, 0xef246, 0xef43a, 0xef64e, 0xef843, 0xefa37, 0xefc4b, 0xefe41,
0xf0054, 0xf0248, 0xf043c, 0xf0650, 0xf0845, 0xf0a38, 0xf0c4d, 0xf0e42, 0xf1037, 0xf124a, 0xf143e, 0xf1651,
0xf1846, 0xf1a3a, 0xf1c4e, 0xf1e44, 0xf2038, 0xf224b, 0xf243f, 0xf2653, 0xf2848, 0xf2a3b, 0xf2c4f, 0xf2e45,
0xf3039, 0xf324d, 0xf3442, 0xf3636, 0xf384a, 0xf3a3d, 0xf3c51, 0xf3e46, 0xf403b, 0xf424e, 0xf4443, 0xf4638,
0xf484c, 0xf4a3f, 0xf4c52, 0xf4e48, 0xf503c, 0xf524f, 0xf5445, 0xf5639, 0xf584d, 0xf5a42, 0xf5c35, 0xf5e49,
0xf603e, 0xf6251, 0xf6446, 0xf663b, 0xf684f, 0xf6a43, 0xf6c37, 0xf6e4b, 0xf703f, 0xf7252, 0xf7447, 0xf763c,
0xf7850, 0xf7a45, 0xf7c39, 0xf7e4d, 0xf8042, 0xf8254, 0xf8449, 0xf863d, 0xf8851, 0xf8a46, 0xf8c3b, 0xf8e4f,
0xf9044, 0xf9237, 0xf944a, 0xf963f, 0xf9853, 0xf9a47, 0xf9c3c, 0xf9e50, 0xfa045, 0xfa238, 0xfa44c, 0xfa641,
0xfa836, 0xfaa49, 0xfac3d, 0xfae52, 0xfb047, 0xfb23a, 0xfb44e, 0xfb643, 0xfb837, 0xfba4a, 0xfbc3f, 0xfbe53,
0xfc048, 0xfc23c, 0xfc450, 0xfc645, 0xfc839, 0xfca4c, 0xfcc41, 0xfce36, 0xfd04a, 0xfd23d, 0xfd451, 0xfd646,
0xfd83a, 0xfda4d, 0xfdc43, 0xfde37, 0xfe04b, 0xfe23f, 0xfe453, 0xfe648, 0xfe83c, 0xfea4f, 0xfec44, 0xfee38,
0xff04c, 0xff241, 0xff436, 0xff64a, 0xff83e, 0xffa51, 0xffc46, 0xffe3a, 0x10004e, 0x100242, 0x100437,
0x10064b, 0x100841, 0x100a53, 0x100c48, 0x100e3c, 0x10104f, 0x101244, 0x101438, 0x10164c, 0x101842,
0x101a35, 0x101c49, 0x101e3d, 0x102051, 0x102245, 0x10243a, 0x10264e, 0x102843, 0x102a37, 0x102c4b,
0x102e3f, 0x103053, 0x103247, 0x10343b, 0x10364f, 0x103845, 0x103a38, 0x103c4c, 0x103e42, 0x104036,
0x104249, 0x10443d, 0x104651, 0x104846, 0x104a3a, 0x104c4e, 0x104e43, 0x105038, 0x10524a, 0x10543e,
0x105652, 0x105847, 0x105a3b, 0x105c4f, 0x105e45, 0x106039, 0x10624c, 0x106441, 0x106635, 0x106849,
0x106a3d, 0x106c51, 0x106e47, 0x10703c, 0x10724f, 0x107444, 0x107638, 0x10784c, 0x107a3f, 0x107c53,
0x107e48};
private static final String[] LUNAR_DAY = {"初一", "初二", "初三", "初四", "初五", "初六", "初七",
"初八", "初九", "初十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八",
"十九", "二十", "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"};
private static final String[] LUNAR_MONTH = {"正月", "二月", "三月", "四月", "五月",
"六月", "七月", "八月", "九月", "十月", "冬月", "腊月"};
private final static String[] LUNAR_HOLIDAY = new String[]{"0101-春节",
"0115-元宵节", "0505-端午节", "0707-七夕", "0815-中秋节", "0909-重阳节"};
private Lunar lunar = new Lunar();
private int lastYear, lastMonth, lastDay;
private int lastLunarDay;
private void setLastData(int year, int month, int day) {
lastYear = year;
lastMonth = month;
lastDay = day;
lastLunarDay = lunar.lunarDay;
}
private boolean initLastData(int year, int month, int day) {
//如果阳历是当在同一年,同一月,day是lastDay的后一天,并且
//阴历lastLunarDay<29的时候,
//此时的阴历直接在前天的基础上加1,否则重新计算
//返回结果是需不需要重新计算,true为重新计算,
// false为在前一天的基础上已经修改了,直接可以使用lunar实例
if (lastYear == year && lastMonth == month && day - lastDay == 1) {
if (lastLunarDay > 0 && lastLunarDay < 29) {
lunar.lunarDay = lastLunarDay + 1;
return false;
}
}
return true;
}
/**
* 公历转农历
*/
String SolarToLunarString(int year, int month, int day) {
Lunar l;
if (initLastData(year, month, day)) {
l = SolarToLunar(year, month, day);
} else {
l = lunar;
}
setLastData(year, month, day);
if (l.lunarDay == 1) {
if (l.lunarMonth == 1) {
return "春节";
}
return LUNAR_MONTH[l.lunarMonth - 1];
} else {
String lunar = String.format("%s.%s", l.lunarMonth, l.lunarDay);
switch (lunar) {
case "1.15":
return "元宵节";
case "5.5":
return "端午节";
case "7.7":
return "七夕";
case "8.15":
return "中秋节";
case "9.9":
return "重阳节";
default:
return LUNAR_DAY[l.lunarDay - 1];
}
}
}
/**
* 公历转农历
*/
private Lunar SolarToLunar(int year, int month, int day) {
int index = year - solar_1_1[0];
int data = (year << 9) | (month << 5) | day;
int solar11;
if (solar_1_1[index] > data) {
index--;
}
solar11 = solar_1_1[index];
int y = GetBitInt(solar11, 12, 9);
int m = GetBitInt(solar11, 4, 5);
int d = GetBitInt(solar11, 5, 0);
long offset = SolarToInt(year, month, day) - SolarToInt(y, m, d);
int days = lunar_month_days[index];
int leap = GetBitInt(days, 4, 13);
int lunarY = index + solar_1_1[0];
int lunarM = 1;
int lunarD = 1;
offset += 1;
for (int i = 0; i < 13; i++) {
int dm = GetBitInt(days, 1, 12 - i) == 1 ? 30 : 29;
if (offset > dm) {
lunarM++;
offset -= dm;
} else {
break;
}
}
lunarD = (int) (offset);
lunar.lunarYear = lunarY;
lunar.lunarMonth = lunarM;
lunar.isleap = false;
if (leap != 0 && lunarM > leap) {
lunar.lunarMonth = lunarM - 1;
if (lunarM == leap + 1) {
lunar.isleap = true;
}
}
lunar.lunarDay = lunarD;
return lunar;
}
private static int GetBitInt(int data, int length, int shift) {
return (data & (((1 << length) - 1) << shift)) >> shift;
}
private static long SolarToInt(int y, int m, int d) {
m = (m + 9) % 12;
y = y - m / 10;
return 365 * y + y / 4 - y / 100 + y / 400 + (m * 306 + 5) / 10 + (d - 1);
}
private static class Lunar {
boolean isleap;
int lunarDay;
int lunarMonth;
int lunarYear;
}
}
2.ZWCalendar(第一个日历)
class ZWCalendar extends View {
private String[] weekTitles = new String[]{"日", "一", "二", "三", "四", "五", "六"};
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
private Calendar calendar = Calendar.getInstance();
//今天所在的年月日信息
private int currentYear, currentMonth, currentDay;
//点击选中的年月日信息
private int clickYear, clickMonth, clickDay;
//当前选择的年月信息
private int selectYear, selectMonth;
private GregorianCalendar date = new GregorianCalendar();
private HashMap<String, Boolean> signRecords;
private GestureDetectorCompat detectorCompat;
private Bitmap signSuccess, signError;
private ZWCalendarView.Config config;
private Paint paint = new Paint();
private LunarHelper lunarHelper;
private int itemWidth, itemHeight;
private float solarTextHeight;
private int currentPosition;
private float signDelay;
public ZWCalendar(Context context) {
super(context);
}
public ZWCalendar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ZWCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
void init(ZWCalendarView.Config config) {
this.config = config;
currentYear = calendar.get(Calendar.YEAR);
currentMonth = calendar.get(Calendar.MONTH);
currentDay = calendar.get(Calendar.DAY_OF_MONTH);
selectYear = currentYear;
selectMonth = currentMonth;
clickYear = currentYear;
clickMonth = currentMonth;
clickDay = currentDay;
detectorCompat = new GestureDetectorCompat(getContext(), gestureListener);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER);
paint.setStrokeWidth(sp2px(0.6f));
currentPosition = (currentYear - 1970) * 12 + currentMonth + 1;
setClickable(true);
if (config.isShowLunar) lunarHelper = new LunarHelper();
if (config.signIconSuccessId != 0) {
signSuccess = BitmapFactory.decodeResource(getResources(), config.signIconSuccessId);
signError = BitmapFactory.decodeResource(getResources(), config.signIconErrorId);
if (signSuccess != null) {
int width = signSuccess.getWidth();
int height = signSuccess.getHeight();
Matrix matrix = new Matrix();
matrix.postScale(config.signIconSize / width, config.signIconSize / height);
signSuccess = Bitmap.createBitmap(signSuccess, 0, 0, width, height, matrix, true);
signError = Bitmap.createBitmap(signError, 0, 0, width, height, matrix, true);
}
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
itemWidth = getWidth() / 7;
itemHeight = (getHeight() - (int) config.weekHeight) / 6;
paint.setTextSize(config.calendarTextSize);
solarTextHeight = getTextHeight();
signDelay = getX(Math.min(itemHeight, itemWidth) / 2, -45);
}
final void selectDate(int position) {
currentPosition = position - 1;
selectYear = 1970 + currentPosition / 12;
selectMonth = currentPosition % 12;
invalidate();
}
final void initSelect(int clickYear, int clickMonth, int clickDay) {
this.clickYear = clickYear;
this.clickMonth = clickMonth;
this.clickDay = clickDay;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
paint.setColor(Color.LTGRAY);
canvas.drawLine(0, config.weekHeight, 0, getHeight() - config.weekHeight, paint);
//画日历顶部周的标题
paint.setColor(config.weekBackgroundColor);
canvas.drawRect(0, 0, getWidth(), config.weekHeight, paint);
paint.setTextSize(config.weekTextSize);
paint.setColor(config.weekTextColor);
float delay = getTextHeight() / 4;
for (int i = 0; i < 7; i++) {
canvas.drawText(weekTitles[i], itemWidth * (i + 0.5f), config.weekHeight / 2 + delay, paint);
}
//画日历
int year = 1970 + currentPosition / 12;
int month = currentPosition % 12;
calendar.set(year, month, 1);
int firstDay = calendar.get(Calendar.DAY_OF_WEEK) - 1;
int selectMonthMaxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
//上一个月的最大天数
calendar.add(Calendar.MONTH, -1);
int previousMonthMaxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
delay = solarTextHeight / 4;
if (config.isShowLunar) delay = 0;
for (int i = 1; i <= 42; i++) {
int copyI = i - 1;
int x = (copyI % 7) * itemWidth + itemWidth / 2;
int y = (copyI / 7) * itemHeight + itemHeight / 2 + (int) config.weekHeight + (int) delay;
if (i <= firstDay) {//前一月数据
if (!config.isShowOtherMonth) continue;
int day = previousMonthMaxDay - firstDay + i;
paint.setColor(config.otherMonthTextColor);
paint.setTextSize(config.calendarTextSize);
canvas.drawText(String.valueOf(day), x, y, paint);
drawLunar(canvas, month == 0 ? (year - 1) : year, month == 0 ? 11 : (month - 1), day, x, y);
} else if (i > selectMonthMaxDay + firstDay) {//后一月数据
if (!config.isShowOtherMonth) continue;
int day = i - firstDay - selectMonthMaxDay;
paint.setColor(config.otherMonthTextColor);
paint.setTextSize(config.calendarTextSize);
canvas.drawText(String.valueOf(day), x, y, paint);
drawLunar(canvas, month == 11 ? (year + 1) : year, month == 11 ? 0 : (month + 1), day, x, y);
} else {//当前月数据
int day = i - firstDay;
if (year == currentYear && month == currentMonth && day == currentDay) {//今天
paint.setColor(config.todayTextColor);
} else {//其他天
paint.setColor(config.calendarTextColor);
}
if (year == clickYear && month == clickMonth && day == clickDay) {//当前选中的一天
paint.setColor(config.selectColor);
canvas.drawCircle(x, y - delay, Math.min(itemHeight, itemWidth) / 2, paint);
paint.setColor(config.selectTextColor);
}
paint.setTextSize(config.calendarTextSize);
drawSign(canvas, year, month, day, x, y);
canvas.drawText(String.valueOf(day), x, y, paint);
drawLunar(canvas, year, month, day, x, y);
}
}
}
private void drawLunar(Canvas canvas, int year, int month, int day, int x, int y) {
if (config.isShowLunar) {
if (year != clickYear || month != clickMonth || day != clickDay) {
paint.setColor(config.lunarTextColor);
}
String lunar = lunarHelper.SolarToLunarString(year, month + 1, day);
paint.setTextSize(config.lunarTextSize);
canvas.drawText(lunar, x, y + solarTextHeight * 2 / 3, paint);
}
}
private void drawSign(Canvas canvas, int year, int month, int day, int x, int y) {
if (signSuccess == null || signRecords == null) return;
date.set(year, month, day);
String dateStr = format.format(date.getTime());
if (signRecords.containsKey(dateStr)) {
if (year != clickYear || month != clickMonth || day != clickDay) {
paint.setColor(config.signTextColor);
}
if (signRecords.get(dateStr)) {
canvas.drawBitmap(signSuccess, x + signDelay - config.signIconSize / 2,
y - signDelay - config.signIconSize / 2, paint);
} else {
canvas.drawBitmap(signError, x + signDelay - config.signIconSize / 2,
y - signDelay - config.signIconSize / 2, paint);
}
}
}
int[] getCurrentDayInfo() {
return new int[]{currentYear, currentMonth, currentDay};
}
private float getX(float radius, int angle) {
int centerX = 0;
return (float) (centerX + radius * Math.cos(angle * 3.14 / 180));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
detectorCompat.onTouchEvent(event);
return super.onTouchEvent(event);
}
private GestureDetector.OnGestureListener
gestureListener = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return super.onDown(e);
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
int position = getPosition(e.getX(), e.getY());
if (dateClickListener != null) {
calendar.set(selectYear, selectMonth, 1);
int firstDay = calendar.get(Calendar.DAY_OF_WEEK) - 1;
calendar.set(selectYear, selectMonth, position - firstDay + 1);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
if (month == selectMonth) {
clickYear = year;
clickMonth = month;
clickDay = day;
invalidate();
dateClickListener.dateSelect(year, month, day, week);
}
}
return super.onSingleTapUp(e);
}
};
private int getPosition(float x, float y) {
y -= config.weekHeight;
int y1 = (int) (y / itemHeight);
int x1 = (int) (x / itemWidth);
return y1 * 7 + x1;
}
void setSignRecords(HashMap<String, Boolean> signRecords) {
this.signRecords = signRecords;
}
private float sp2px(float spValue) {
float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
return spValue * fontScale + 0.5f;
}
private float getTextHeight() {
return paint.descent() - paint.ascent();
}
interface DateSelectListener {
void dateSelect(int year, int month, int day, int week);
}
private DateSelectListener dateClickListener;
void setDateSelectListener(DateSelectListener clickListener) {
dateClickListener = clickListener;
}
}
3.ZWCalendarView(第一个日历)
public class ZWCalendarView extends FrameLayout {
private ArraySet<ZWCalendar> destroyViews = new ArraySet<>();
private ArraySet<ZWCalendar> viewSet = new ArraySet<>();
private int selectYear, selectMonth, selectDay, selectWeek;
private HashMap<String, Boolean> signRecords;
private int PAGER_SIZE = 1200;
private Calendar calendar;
private ViewPager pager;
private Config config;
public ZWCalendarView(Context context) {
super(context);
init(null, 0);
}
public ZWCalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public ZWCalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr);
}
private void init(AttributeSet attrs, int def) {
config = new Config();
//获取日历的UI配置
TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.ZWCalendarView, def, 0);
config.weekHeight = array.getDimension(R.styleable.ZWCalendarView_weekHeight, dip2px(30));
config.weekBackgroundColor = array.getColor(R.styleable.ZWCalendarView_weekBackgroundColor, Color.WHITE);
config.weekTextColor = array.getColor(R.styleable.ZWCalendarView_weekTextColor, Color.GRAY);
config.weekTextSize = array.getDimension(R.styleable.ZWCalendarView_weekTextSize, sp2px(14));
config.calendarTextColor = array.getColor(R.styleable.ZWCalendarView_calendarTextColor, Color.BLACK);
config.calendarTextSize = array.getDimension(R.styleable.ZWCalendarView_calendarTextSize, sp2px(14));
config.isShowOtherMonth = array.getBoolean(R.styleable.ZWCalendarView_isShowOtherMonth, false);
if (config.isShowOtherMonth) {
config.otherMonthTextColor = array.getColor(R.styleable.ZWCalendarView_otherMonthTextColor, Color.LTGRAY);
}
config.isShowLunar = array.getBoolean(R.styleable.ZWCalendarView_isShowLunar, false);
if (config.isShowLunar) {
config.lunarTextColor = array.getColor(R.styleable.ZWCalendarView_lunarTextColor, Color.LTGRAY);
config.lunarTextSize = array.getDimension(R.styleable.ZWCalendarView_lunarTextSize, sp2px(11));
}
config.todayTextColor = array.getColor(R.styleable.ZWCalendarView_todayTextColor, Color.BLUE);
config.selectColor = array.getColor(R.styleable.ZWCalendarView_selectColor, Color.BLUE);
config.selectTextColor = array.getColor(R.styleable.ZWCalendarView_selectTextColor, Color.WHITE);
config.signIconSuccessId = array.getResourceId(R.styleable.ZWCalendarView_signIconSuccessId, 0);
config.signIconErrorId = array.getResourceId(R.styleable.ZWCalendarView_signIconErrorId, 0);
if (config.signIconSuccessId != 0) {
config.signIconSize = array.getDimension(R.styleable.ZWCalendarView_signIconSize, dip2px(16));
}
config.signTextColor = array.getColor(R.styleable.ZWCalendarView_signTextColor, Color.parseColor("#BA7436"));
config.limitFutureMonth = array.getBoolean(R.styleable.ZWCalendarView_limitFutureMonth, false);
array.recycle();
initPager();
}
private float sp2px(float spValue) {
float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
return spValue * fontScale + 0.5f;
}
private int dip2px(float dipValue) {
final float scale = Resources.getSystem().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int hMode = MeasureSpec.getMode(heightMeasureSpec);
height = hMode == MeasureSpec.EXACTLY ? height : dip2px(220);
setMeasuredDimension(widthMeasureSpec, height);
}
private void initPager() {
pager = new ViewPager(getContext());
addView(pager);
pager.setOffscreenPageLimit(1);
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (listener == null) return;
position -= 1;
int year = 1970 + position / 12;
int month = position % 12;
listener.change(year, month + 1);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
//选择当前日期
calendar = Calendar.getInstance();
selectYear = calendar.get(Calendar.YEAR);
selectMonth = calendar.get(Calendar.MONTH);
selectDay = calendar.get(Calendar.DAY_OF_MONTH);
selectWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
int currentPosition = getPosition(selectYear, selectMonth);
if (config.limitFutureMonth) PAGER_SIZE = currentPosition + 1;
pager.setAdapter(new CVAdapter());
pager.setCurrentItem(currentPosition, false);
}
private int getPosition(int year, int month) {
return (year - 1970) * 12 + month + 1;
}
private class CVAdapter extends PagerAdapter {
@Override
public int getCount() {
return PAGER_SIZE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
ZWCalendar calendarView = getContent(position);
container.addView(calendarView);
return calendarView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
destroyViews.add((ZWCalendar) object);
container.removeView((View) object);
}
}
private ZWCalendar getContent(int position) {
ZWCalendar calendarView;
if (destroyViews.size() != 0) {
calendarView = destroyViews.valueAt(0);
destroyViews.remove(calendarView);
} else {
calendarView = new ZWCalendar(getContext());
calendarView.init(config);
calendarView.setDateSelectListener(new ZWCalendar.DateSelectListener() {
@Override
public void dateSelect(int year, int month, int day, int week) {
selectYear = year;
selectMonth = month;
selectDay = day;
for (ZWCalendar view : viewSet) {
view.initSelect(selectYear, selectMonth, selectDay);
}
if (listener != null) {
listener.select(year, month + 1, day, week == 0 ? 7 : week);
}
}
});
viewSet.add(calendarView);
}
calendarView.setSignRecords(signRecords);
calendarView.selectDate(position);
calendarView.setTag(position);
return calendarView;
}
static class Config {
float weekHeight;
float weekTextSize;
int weekBackgroundColor;
int weekTextColor;
float calendarTextSize;
int calendarTextColor;
boolean isShowOtherMonth;
int otherMonthTextColor;
boolean isShowLunar;
int lunarTextColor;
float lunarTextSize;
int todayTextColor;
int selectColor;
int selectTextColor;
int signIconSuccessId;
int signIconErrorId;
float signIconSize;
int signTextColor;
boolean limitFutureMonth;
}
/*---------------------------------------对外方法-----------------------------------*/
public interface SelectListener {
void change(int year, int month);
void select(int year, int month, int day, int week);
}
private SelectListener listener;
public void setSelectListener(SelectListener listener) {
this.listener = listener;
listener.change(selectYear, selectMonth + 1);
selectWeek = selectWeek == 0 ? 7 : selectWeek;
listener.select(selectYear, selectMonth + 1, selectDay, selectWeek);
}
public void selectDate(int year, int month, int day) {
if (listener == null || year < 1970 || month < 1 || month > 12 || day < 1 || day > 31)
return;
month -= 1;
calendar.set(year, month, day);
int yearTemp = calendar.get(Calendar.YEAR);
int monthTemp = calendar.get(Calendar.MONTH);
int dayTemp = calendar.get(Calendar.DAY_OF_MONTH);
if (yearTemp != year || monthTemp != month || dayTemp != day) return;
selectYear = year;
selectMonth = month;
selectDay = day;
for (ZWCalendar view : viewSet) {
view.initSelect(selectYear, selectMonth, selectDay);
}
int position = getPosition(selectYear, selectMonth);
pager.setCurrentItem(position, false);
int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
listener.select(selectYear, selectMonth + 1, selectDay, week == 0 ? 7 : week);
}
public void selectMonth(int year, int month) {
if (pager == null || year < 1970 || month < 1 || month > 12) return;
int position = getPosition(year, month);
pager.setCurrentItem(position, false);
}
/**
* 设置签到记录
*
* @param signRecords 为日期格式像 "2017-08-25"
*/
public void setSignRecords(final HashMap<String, Boolean> signRecords) {
if (signRecords == null) return;
this.signRecords = signRecords;
for (ZWCalendar view : viewSet) {
view.setSignRecords(signRecords);
view.invalidate();
}
}
public void showNextMonth() {
if (pager != null) {
int index = pager.getCurrentItem() + 1;
pager.setCurrentItem(index, true);
}
}
public void showPreviousMonth() {
if (pager != null) {
int index = pager.getCurrentItem() - 1;
pager.setCurrentItem(index, true);
}
}
public void backToday() {
if (pager != null) {
ZWCalendar item = (ZWCalendar) pager.findViewWithTag(pager.getCurrentItem());
if (item != null) {
int[] info = item.getCurrentDayInfo();
selectDate(info[0], info[1] + 1, info[2]);
}
}
}
}
4.ZWSignCalendar(第二个日历)
class ZWSignCalendar extends View {
private String[] weekTitles = new String[]{"日", "一", "二", "三", "四", "五", "六"};
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
private Calendar calendar = Calendar.getInstance();
//今天所在的年月日信息
private int currentYear, currentMonth, currentDay;
private GregorianCalendar date = new GregorianCalendar();
private ZWSignCalendarView.Config config;
private HashSet<String> signRecords;
private Paint paint = new Paint();
private LunarHelper lunarHelper;
private int itemWidth, itemHeight;
private float solarTextHeight;
private int currentPosition;
public ZWSignCalendar(Context context) {
super(context);
}
public ZWSignCalendar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ZWSignCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
void init(ZWSignCalendarView.Config config) {
this.config = config;
currentYear = calendar.get(Calendar.YEAR);
currentMonth = calendar.get(Calendar.MONTH);
currentDay = calendar.get(Calendar.DAY_OF_MONTH);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER);
paint.setStrokeWidth(sp2px(0.6f));
currentPosition = (currentYear - 1970) * 12 + currentMonth + 1;
setClickable(true);
if (config.isShowLunar) lunarHelper = new LunarHelper();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
itemWidth = getWidth() / 7;
itemHeight = (getHeight() - (int) config.weekHeight) / 6;
paint.setTextSize(config.calendarTextSize);
solarTextHeight = getTextHeight();
if (config.signSize == 0) config.signSize = Math.min(itemHeight, itemWidth);
}
final void selectDate(int position) {
currentPosition = position - 1;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
paint.setColor(Color.LTGRAY);
canvas.drawLine(0, config.weekHeight, 0, getHeight() - config.weekHeight, paint);
//画日历顶部周的标题
paint.setColor(config.weekBackgroundColor);
canvas.drawRect(0, 0, getWidth(), config.weekHeight, paint);
paint.setTextSize(config.weekTextSize);
paint.setColor(config.weekTextColor);
float delay = getTextHeight() / 4;
for (int i = 0; i < 7; i++) {
canvas.drawText(weekTitles[i], itemWidth * (i + 0.5f), config.weekHeight / 2 + delay, paint);
}
//画日历
int year = 1970 + currentPosition / 12;
int month = currentPosition % 12;
calendar.set(year, month, 1);
int firstDay = calendar.get(Calendar.DAY_OF_WEEK) - 1;
int selectMonthMaxDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
delay = solarTextHeight / 4;
if (config.isShowLunar) delay = 0;
for (int i = 1; i <= selectMonthMaxDay; i++) {
int position = i - 1 + firstDay;
int x = (position % 7) * itemWidth + itemWidth / 2;
int y = (position / 7) * itemHeight + itemHeight / 2 + (int) config.weekHeight + (int) delay;
int day = i;
//签到背景
boolean isSign = false;
if (signRecords != null) {
date.set(year, month, day);
String dateStr = format.format(date.getTime());
if (signRecords.contains(dateStr)) {
paint.setColor(config.signColor);
canvas.drawCircle(x, y, config.signSize / 2, paint);
isSign = true;
}
}
//农历
if (config.isShowLunar) {
paint.setColor(isSign ? config.signTextColor : config.lunarTextColor);
String lunar = lunarHelper.SolarToLunarString(year, month + 1, day);
paint.setTextSize(config.lunarTextSize);
canvas.drawText(lunar, x, y + solarTextHeight * 2 / 3, paint);
}
//阳历
if (isSign) {
paint.setColor(config.signTextColor);
} else if (year == currentYear && month == currentMonth && day == currentDay) {//今天
paint.setColor(config.todayTextColor);
} else {//其他天
paint.setColor(config.calendarTextColor);
}
paint.setTextSize(config.calendarTextSize);
canvas.drawText(String.valueOf(day), x, y, paint);
}
}
void setSignRecords(HashSet<String> signRecords) {
this.signRecords = signRecords;
}
private float sp2px(float spValue) {
float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
return spValue * fontScale + 0.5f;
}
private float getTextHeight() {
return paint.descent() - paint.ascent();
}
}
5.ZWSignCalendarView(第二个日历)
public class ZWSignCalendarView extends FrameLayout {
private ArraySet<ZWSignCalendar> destroyViews = new ArraySet<>();
private ArraySet<ZWSignCalendar> viewSet = new ArraySet<>();
private HashSet<String> signRecords;
private int PAGER_SIZE = 1200;
private ViewPager pager;
private Config config;
private int currentPosition;
public ZWSignCalendarView(Context context) {
super(context);
init(null, 0);
}
public ZWSignCalendarView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public ZWSignCalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr);
}
private void init(AttributeSet attrs, int def) {
config = new Config();
//获取日历的UI配置
TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.ZWSignCalendarView, def, 0);
config.weekHeight = array.getDimension(R.styleable.ZWSignCalendarView_weekHeight, dip2px(30));
config.weekBackgroundColor = array.getColor(R.styleable.ZWSignCalendarView_weekBackgroundColor, Color.WHITE);
config.weekTextColor = array.getColor(R.styleable.ZWSignCalendarView_weekTextColor, Color.GRAY);
config.weekTextSize = array.getDimension(R.styleable.ZWSignCalendarView_weekTextSize, sp2px(14));
config.calendarTextColor = array.getColor(R.styleable.ZWSignCalendarView_calendarTextColor, Color.BLACK);
config.calendarTextSize = array.getDimension(R.styleable.ZWSignCalendarView_calendarTextSize, sp2px(14));
config.isShowLunar = array.getBoolean(R.styleable.ZWSignCalendarView_isShowLunar, false);
if (config.isShowLunar) {
config.lunarTextColor = array.getColor(R.styleable.ZWSignCalendarView_lunarTextColor, Color.LTGRAY);
config.lunarTextSize = array.getDimension(R.styleable.ZWSignCalendarView_lunarTextSize, sp2px(11));
}
config.todayTextColor = array.getColor(R.styleable.ZWSignCalendarView_todayTextColor, Color.BLUE);
config.signSize = array.getDimension(R.styleable.ZWSignCalendarView_signSize, 0);
config.signTextColor = array.getColor(R.styleable.ZWSignCalendarView_signTextColor, Color.parseColor("#BA7436"));
config.limitFutureMonth = array.getBoolean(R.styleable.ZWSignCalendarView_limitFutureMonth, false);
config.signColor = array.getColor(R.styleable.ZWSignCalendarView_signColor, Color.BLUE);
array.recycle();
initPager();
}
private float sp2px(float spValue) {
float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
return spValue * fontScale + 0.5f;
}
private int dip2px(float dipValue) {
final float scale = Resources.getSystem().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int hMode = MeasureSpec.getMode(heightMeasureSpec);
height = hMode == MeasureSpec.EXACTLY ? height : dip2px(220);
setMeasuredDimension(widthMeasureSpec, height);
}
private void initPager() {
pager = new ViewPager(getContext());
addView(pager);
pager.setOffscreenPageLimit(1);
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (listener == null) return;
position -= 1;
int year = 1970 + position / 12;
int month = position % 12;
listener.change(year, month + 1);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
//选择当前日期
Calendar calendar = Calendar.getInstance();
final int year = calendar.get(Calendar.YEAR);
final int month = calendar.get(Calendar.MONTH);
currentPosition = getPosition(year, month);
if (config.limitFutureMonth) PAGER_SIZE = currentPosition + 1;
pager.setAdapter(new CVAdapter());
pager.setCurrentItem(currentPosition, false);
post(new Runnable() {
public void run() {
if (listener != null) listener.change(year, month + 1);
}
});
}
private int getPosition(int year, int month) {
return (year - 1970) * 12 + month + 1;
}
private class CVAdapter extends PagerAdapter {
@Override
public int getCount() {
return PAGER_SIZE;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
ZWSignCalendar calendarView = getContent(position);
container.addView(calendarView);
return calendarView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
destroyViews.add((ZWSignCalendar) object);
container.removeView((View) object);
}
}
private ZWSignCalendar getContent(int position) {
ZWSignCalendar calendarView;
if (destroyViews.size() != 0) {
calendarView = destroyViews.valueAt(0);
destroyViews.remove(calendarView);
} else {
calendarView = new ZWSignCalendar(getContext());
calendarView.init(config);
viewSet.add(calendarView);
}
calendarView.setSignRecords(signRecords);
calendarView.selectDate(position);
calendarView.setTag(position);
return calendarView;
}
static class Config {
float weekHeight;
float weekTextSize;
int weekBackgroundColor;
int weekTextColor;
float calendarTextSize;
int calendarTextColor;
boolean isShowLunar;
int lunarTextColor;
float lunarTextSize;
int todayTextColor;
int signColor;
float signSize;
int signTextColor;
boolean limitFutureMonth;
}
/*---------------------------------------对外方法-----------------------------------*/
public interface DateListener {
void change(int year, int month);
}
private DateListener listener;
public void setDateListener(DateListener listener) {
this.listener = listener;
}
public void selectMonth(int year, int month) {
if (pager == null || year < 1970 || month < 1 || month > 12) return;
int position = getPosition(year, month);
pager.setCurrentItem(position, false);
}
/**
* 设置签到记录
*
* @param signRecords 为日期格式像 "2017-08-25"
*/
public void setSignRecords(final HashSet<String> signRecords) {
if (signRecords == null) return;
this.signRecords = signRecords;
for (ZWSignCalendar view : viewSet) {
view.setSignRecords(signRecords);
view.invalidate();
}
}
public void showNextMonth() {
if (pager != null) {
int index = pager.getCurrentItem() + 1;
pager.setCurrentItem(index, true);
}
}
public void showPreviousMonth() {
if (pager != null) {
int index = pager.getCurrentItem() - 1;
pager.setCurrentItem(index, true);
}
}
public void backCurrentMonth() {
if (pager != null) {
pager.setCurrentItem(currentPosition, false);
}
}
}
6.activity_main
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/calendar_previous"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:rotation="180"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_calendar_show"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:padding="5dp"
android:text="222"
android:textColor="#333333"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_calendar_today"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="5dp"
android:text="今天"
android:textColor="#333333"
android:textSize="14sp" />
<ImageView
android:id="@+id/calendar_next"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" />
</LinearLayout>
<com.yjjk.date_two.ZWCalendarView
android:id="@+id/calendarView"
android:layout_width="match_parent"
android:layout_height="250dp"
app:calendarTextSize="14sp"
app:isShowLunar="true"
app:isShowOtherMonth="false"
app:limitFutureMonth="true"
app:lunarTextSize="9sp"
app:selectColor="#5675F2"
app:signIconErrorId="@mipmap/record_error"
app:signIconSuccessId="@mipmap/record_success"
app:signTextColor="@android:color/holo_green_dark"
app:weekTextColor="#BA7436"
app:weekTextSize="13sp">
</com.yjjk.date_two.ZWCalendarView>
<View
android:layout_width="match_parent"
android:layout_height="10dp"
android:background="#999999" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/calendar_previous2"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:rotation="180"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_calendar_show2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:padding="5dp"
android:text="222"
android:textColor="#333333"
android:textSize="14sp" />
<TextView
android:id="@+id/tv_calendar_today2"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="5dp"
android:text="今天"
android:textColor="#333333"
android:textSize="14sp" />
<ImageView
android:id="@+id/calendar_next2"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher" />
</LinearLayout>
<com.yjjk.date_two.ZWSignCalendarView
android:id="@+id/calendarView2"
android:layout_width="match_parent"
android:layout_height="250dp"
app:calendarTextSize="14sp"
app:isShowLunar="true"
app:isShowOtherMonth="false"
app:limitFutureMonth="false"
app:lunarTextSize="9sp"
app:signColor="#5675F2"
app:signSize="35sp"
app:signTextColor="#FFFFFF"
app:todayTextColor="@android:color/holo_red_light"
app:weekTextColor="#BA7436"
app:weekTextSize="13sp">
</com.yjjk.date_two.ZWSignCalendarView>
</LinearLayout>
</ScrollView>
7.MainActivity
public class MainActivity extends AppCompatActivity {
private ZWCalendarView calendarView;
private ZWSignCalendarView signCalendarView;
private TextView show, show2;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
calendarView = (ZWCalendarView) findViewById(R.id.calendarView);
show = (TextView) findViewById(R.id.tv_calendar_show);
show2 = (TextView) findViewById(R.id.tv_calendar_show2);
calendarView.setSelectListener(new ZWCalendarView.SelectListener() {
@Override
public void change(int year, int month) {
show.setText(String.format("%s 年 %s 月", year, month));
}
@Override
public void select(int year, int month, int day, int week) {
Toast.makeText(getApplicationContext(),
String.format("%s 年 %s 月 %s日,周%s", year, month, day, week),
Toast.LENGTH_SHORT).show();
}
});
//代码选中一个日期
show.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
calendarView.selectDate(2017, 9, 3);
}
});
//前一月
findViewById(R.id.calendar_previous).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
calendarView.showPreviousMonth();
}
});
//后一月
findViewById(R.id.calendar_next).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
calendarView.showNextMonth();
}
});
//返回今天
findViewById(R.id.tv_calendar_today).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
calendarView.backToday();
}
});
HashMap<String, Boolean> sign = new HashMap<>();
sign.put("2019-07-12", true);
sign.put("2019-07-23", true);
sign.put("2019-07-24", false);
sign.put("2019-07-25", true);
sign.put("2019-08-12", false);
sign.put("2019-08-13", true);
sign.put("2019-08-14", true);
sign.put("2019-08-15", false);
sign.put("2019-08-18", false);
sign.put("2019-08-31", true);
sign.put("2019-09-05", true);
sign.put("2019-09-07", false);
sign.put("2019-09-08", false);
sign.put("2019-09-09", true);
sign.put("2019-10-09", true);
calendarView.setSignRecords(sign);
//
//
/*------------------------------------------------------------------------------*/
//
//
signCalendarView = (ZWSignCalendarView) findViewById(R.id.calendarView2);
signCalendarView.setDateListener(new ZWSignCalendarView.DateListener() {
@Override
public void change(int year, int month) {
show2.setText(String.format("%s 年 %s 月", year, month));
}
});
show2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signCalendarView.selectMonth(2017, 9);
}
});
findViewById(R.id.calendar_previous2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signCalendarView.showPreviousMonth();
}
});
findViewById(R.id.calendar_next2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signCalendarView.showNextMonth();
}
});
findViewById(R.id.tv_calendar_today2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
signCalendarView.backCurrentMonth();
}
});
HashSet<String> sign2 = new HashSet<>();
sign2.add("2017-07-12");
sign2.add("2017-07-23");
sign2.add("2017-07-24");
sign2.add("2017-07-25");
sign2.add("2017-08-12");
sign2.add("2017-08-13");
sign2.add("2017-08-14");
sign2.add("2017-08-15");
sign2.add("2017-08-18");
sign2.add("2017-08-31");
sign2.add("2017-09-05");
sign2.add("2017-09-07");
sign2.add("2017-09-08");
sign2.add("2017-09-09");
sign2.add("2017-10-09");
signCalendarView.setSignRecords(sign2);
}
}
8.在values布局中创建arrt
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ZWCalendarView">
<attr name="weekHeight" />
<attr name="weekTextSize" />
<attr name="weekBackgroundColor" />
<attr name="weekTextColor" />
<attr name="calendarTextSize" />
<attr name="calendarTextColor" />
<attr name="isShowOtherMonth" format="boolean" />
<attr name="otherMonthTextColor" format="color" />
<attr name="isShowLunar" />
<attr name="lunarTextColor" />
<attr name="lunarTextSize" />
<attr name="todayTextColor" />
<attr name="selectColor" format="color" />
<attr name="selectTextColor" format="color" />
<attr name="signIconSuccessId" format="integer" />
<attr name="signIconErrorId" format="integer" />
<attr name="signIconSize" format="dimension" />
<attr name="signTextColor" />
<attr name="limitFutureMonth" />
</declare-styleable>
<attr name="weekHeight" format="dimension" />
<attr name="weekTextSize" format="dimension" />
<attr name="weekBackgroundColor" format="color" />
<attr name="weekTextColor" format="color" />
<attr name="calendarTextSize" format="dimension" />
<attr name="calendarTextColor" format="color" />
<attr name="isShowLunar" format="boolean" />
<attr name="lunarTextColor" format="color" />
<attr name="lunarTextSize" format="dimension" />
<attr name="todayTextColor" format="color" />
<attr name="signTextColor" format="color" />
<attr name="limitFutureMonth" format="boolean" />
<declare-styleable name="ZWSignCalendarView">
<attr name="weekHeight" />
<attr name="weekTextSize" />
<attr name="weekBackgroundColor" />
<attr name="weekTextColor" />
<attr name="calendarTextSize" />
<attr name="calendarTextColor" />
<attr name="isShowLunar" />
<attr name="lunarTextColor" />
<attr name="lunarTextSize" />
<attr name="todayTextColor" />
<attr name="signColor" format="color" />
<attr name="signSize" format="dimension" />
<attr name="signTextColor" />
<attr name="limitFutureMonth" />
</declare-styleable>
</resources>
版权声明:本文为weixin_42630638原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。