https://github.com/huanghaibin-dev/CalendarViewjava
compile 'com.haibin:calendarview:3.2.9'
复制代码
<dependency>
<groupId>com.haibin</groupId>
<artifactId>calendarview</artifactId>
<version>3.2.9</version>
<type>pom</type>
</dependency>
复制代码
-keepclasseswithmembers class * {
public <init>(android.content.Context);
}
复制代码
这是个辅助类,负责CalendarView的收缩控制功能,若是不须要收缩功能,无需使用它,通常使用教程以下android
<com.haibin.calendarview.CalendarLayout android:id="@+id/calendarLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#fff" app:only_week_view="false" app:default_status="shrink" app:calendar_content_view_id="@+id/recyclerView">
<com.haibin.calendarview.CalendarView android:id="@+id/calendarView" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#fff" app:current_month_text_color="#333333" app:current_month_lunar_text_color="#CFCFCF" app:min_year="2004" app:max_year="2020" app:other_month_text_color="#e1e1e1" app:other_month_lunar_text_color="#e1e1e1" app:scheme_text="假" app:week_start_with="mon" app:scheme_text_color="#333" app:scheme_theme_color="#128c4b" app:selected_lunar_text_color="#CFCFCF" app:month_view="com.haibin.calendarviewproject.meizu.MeiZuMonthView" app:week_view="com.haibin.calendarviewproject.meizu.MeizuWeekView" app:selected_text_color="#333" app:selected_theme_color="#108cd4" app:week_background="#fff" app:week_text_color="#111" app:year_view_day_text_color="#333333" app:year_view_day_text_size="9sp" app:year_view_month_text_color="#ff0000" app:year_view_month_text_size="20sp" app:month_view_show_mode="mode_only_current" app:year_view_scheme_color="#f17706"/>
<com.haibin.calendarviewproject.group.GroupRecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/content_background" />
</com.haibin.calendarview.CalendarLayout>
复制代码
public void expand(); //展开
public void shrink(); //收缩
public boolean isExpand();//是否已经展开
复制代码
<!-- 日历显示模式 -->
<attr name="calendar_show_mode">
<enum name="both_month_week_view" value="0" /><!-- 默认都有 -->
<enum name="only_week_view" value="1" /><!-- 仅周视图 -->
<enum name="only_month_view" value="2" /><!-- 仅月视图 -->
</attr>
<attr name="default_status">
<enum name="expand" value="0" /> <!--默认展开-->
<enum name="shrink" value="1" /><!--默认搜索-->
</attr>
<attr name="calendar_content_view_id" format="integer" /><!--内容布局id-->
复制代码
真正的日历类,能够自行经过attr配置git
<com.haibin.calendarview.CalendarView android:id="@+id/calendarView" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#fff" app:current_month_text_color="#333333" app:current_month_lunar_text_color="#CFCFCF" app:min_year="2004" app:max_year="2020" app:other_month_text_color="#e1e1e1" app:other_month_lunar_text_color="#e1e1e1" app:scheme_text="假" app:scheme_text_color="#333" app:scheme_theme_color="#128c4b" app:selected_lunar_text_color="#CFCFCF" app:month_view="com.haibin.calendarviewproject.meizu.MeiZuMonthView" app:week_view="com.haibin.calendarviewproject.meizu.MeizuWeekView" app:selected_text_color="#333" app:selected_theme_color="#108cd4" app:week_background="#fff" app:week_text_color="#111" app:year_view_day_text_color="#333333" app:year_view_day_text_size="9sp" app:year_view_month_text_color="#ff0000" app:year_view_month_text_size="20sp" app:year_view_scheme_color="#f17706"/>
复制代码
<declare-styleable name="CalendarView">
<attr name="week_background" format="color" /><!--星期栏背景色-->
<attr name="week_line_background" format="color" /><!--星期栏线的颜色-->
<attr name="week_text_color" format="color" /><!--星期栏文本颜色-->
<attr name="week_bar_view" format="string" /><!--若是须要的话使用自定义星期栏-->
<attr name="month_view" format="string" /><!--彻底自定义月视图路径-->
<attr name="week_view" format="string" /><!--彻底自定义周视图路径-->
<attr name="scheme_text" format="string" /><!--标记的文本,通常可忽略-->
<attr name="day_text_size" format="dimension" /><!--日期字体大小-->
<attr name="lunar_text_size" format="dimension" /><!--农历字体大小-->
<attr name="calendar_height" format="dimension" /><!--日历卡的高度,每一项,不是总体-->
<attr name="scheme_text_color" format="color" /><!--标记的文本颜色-->
<attr name="scheme_month_text_color" format="color" /><!--标记的月字体颜色-->
<attr name="scheme_lunar_text_color" format="color" /><!--标记的农历字体颜色-->
<attr name="scheme_theme_color" format="color" /><!--标记的背景主题颜色-->
<attr name="selected_theme_color" format="color" /><!--选择的背景主题颜色-->
<attr name="selected_text_color" format="color" /><!--选中的月字体颜色-->
<attr name="selected_lunar_text_color" format="color" /><!--选中的农历字体颜色-->
<attr name="current_day_text_color" format="color" /><!--今天的日子字体颜色-->
<attr name="current_day_lunar_text_color" format="color" /><!--今天的日子农历字体颜色-->
<attr name="current_month_text_color" format="color" /><!--当前月份卡的月字体颜色,非今天所在的月份-->
<attr name="other_month_text_color" format="color" /><!--当前月份卡其它月字体颜色-->
<attr name="current_month_lunar_text_color" format="color" /><!--当前月份月农历颜色-->
<attr name="other_month_lunar_text_color" format="color" /><!--其它月份农历字体颜色-->
<!-- 年视图相关 -->
<attr name="year_view_month_text_size" format="dimension" /><!--年视图月字体大小-->
<attr name="year_view_day_text_size" format="dimension" /><!--年视图日字体大小-->
<attr name="year_view_month_text_color" format="color" /><!--年视图月字体颜色-->
<attr name="year_view_day_text_color" format="color" /><!--年视图日子字体颜色-->
<attr name="year_view_scheme_color" format="color" /><!--年视图标记字体颜色-->
<attr name="year_view_background" format="color" /><!--年视图背景-->
<!---->
<attr name="min_year" format="integer" /><!--最小年份-->
<attr name="max_year" format="integer" /><!--最大年份-->
<attr name="min_year_month" format="integer" /><!--最小年份对应最小月份-->
<attr name="max_year_month" format="integer" /><!--最大年份对应月份-->
<!--配置你喜欢的月视图显示模式模式-->
<attr name="month_view_show_mode">
<enum name="mode_all" value="0" /> <!--所有显示-->
<enum name="mode_only_current" value="1" /> <!--仅显示当前月份-->
<enum name="mode_fix" value="2" /> <!--自适应显示,不会多出一行,可是会自动填充-->
</attr>
<!-- 自定义周起始 -->
<attr name="week_start_with">
<enum name="sun" value="1" />
<enum name="mon" value="2" />
<enum name="sat" value="7" />
</attr>
</declare-styleable>
复制代码
public int getCurDay(); //今天
public int getCurMonth(); //当前的月份
public int getCurYear(); //今年
public void showSelectLayout(final int year); //快速弹出年份选择月份
public void closeSelectLayout(final int position); //关闭选择年份并跳转日期
/** * 设置日期范围 * * @param minYear 最小年份 * @param minYearMonth 最小年份对应月份 * @param maxYear 最大月份 * @param maxYearMonth 最大月份对应月份 */
public void setRange(int minYear, int minYearMonth, int maxYear, int maxYearMonth) public void setOnYearChangeListener(OnYearChangeListener listener);//年份切换事件
public void setOnDateSelectedListener(OnDateSelectedListener listener);//日期选择事件
public void setSchemeDate(List<Calendar> mSchemeDate);//标记日期
public void update();//动态更新
public Calendar getSelectedCalendar(); //获取选择的日期
public void scrollToPre();//滚动到上一个月
public void scrollToNext();//滚动到下一个月
public void scrollToCalendar(int year, int month, int day);//滚动到指定日期
/** * 设置背景色 * * @param monthLayoutBackground 月份卡片的背景色 * @param weekBackground 星期栏背景色 * @param lineBg 线的颜色 */
public void setBackground(int monthLayoutBackground, int weekBackground, int lineBg) /** * 设置文本颜色 * * @param curMonthTextColor 当前月份字体颜色 * @param otherMonthColor 其它月份字体颜色 * @param lunarTextColor 农历字体颜色 */ public void setTextColor(int curMonthTextColor,int otherMonthColor,int lunarTextColor) /** * 设置选择的效果 * * @param style 选中的style CalendarCardView.STYLE_FILL or CalendarCardView.STYLE_STROKE * @param selectedThemeColor 选中的标记颜色 * @param selectedTextColor 选中的字体颜色 */ public void setSelectedColor(int style, int selectedThemeColor, int selectedTextColor) /** * 设置标记的色 * * @param style 标记的style CalendarCardView.STYLE_FILL or CalendarCardView.STYLE_STROKE * @param schemeColor 标记背景色 * @param schemeTextColor 标记字体颜色 */ public void setSchemeColor(int style, int schemeColor, int schemeTextColor) /** * 设置背景色 * * @param yearViewBackground 年份卡片的背景色 * @param weekBackground 星期栏背景色 * @param lineBg 线的颜色 */ public void setBackground(int yearViewBackground, int weekBackground, int lineBg) 复制代码
onDrawSelected
onDrawScheme
onDrawText
复制代码
/** * 首先继承月视图,假如咱们想实现高仿魅族的日历 */
public class MeiZuMonthView extends MonthView {
/** * 自定义魅族标记的文本画笔 */
private Paint mTextPaint = new Paint();
/** * 自定义魅族标记的圆形背景 */
private Paint mSchemeBasicPaint = new Paint();
private float mRadio;
private int mPadding;
private float mSchemeBaseLine;
public MeiZuMonthView(Context context) {
super(context);
mTextPaint.setTextSize(dipToPx(context, 8));
mTextPaint.setColor(0xffffffff);
mTextPaint.setAntiAlias(true);
mTextPaint.setFakeBoldText(true);
mSchemeBasicPaint.setAntiAlias(true);
mSchemeBasicPaint.setStyle(Paint.Style.FILL);
mSchemeBasicPaint.setTextAlign(Paint.Align.CENTER);
mSchemeBasicPaint.setFakeBoldText(true);
mRadio = dipToPx(getContext(), 7);
mPadding = dipToPx(getContext(), 4);
Paint.FontMetrics metrics = mSchemeBasicPaint.getFontMetrics();
mSchemeBaseLine = mRadio - metrics.descent + (metrics.bottom - metrics.top) / 2 + dipToPx(getContext(), 1);
}
/** * 绘制选中的日子 * @param canvas canvas * @param calendar 日历日历calendar * @param x 日历Card x起点坐标 * @param y 日历Card y起点坐标 * @param hasScheme hasScheme 非标记的日期 * @return 返回true 则会继续绘制onDrawScheme,由于这里背景色不是是互斥的,因此返回true,返回false,则点击scheme标记的日子,则不继续绘制onDrawScheme,自行选择便可 */
@Override
protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme) {
mSelectedPaint.setStyle(Paint.Style.FILL);
mSelectedPaint.setColor(0x80cfcfcf);
canvas.drawRect(x + mPadding, y + mPadding, x + mItemWidth - mPadding, y + mItemHeight - mPadding, mSelectedPaint);
return true;
}
/** * 绘制标记的事件日子 * @param canvas canvas * @param calendar 日历calendar * @param x 日历Card x起点坐标 * @param y 日历Card y起点坐标 */
@Override
protected void onDrawScheme(Canvas canvas, Calendar calendar, int x, int y) {
mSchemeBasicPaint.setColor(calendar.getSchemeColor());
canvas.drawCircle(x + mItemWidth - mPadding - mRadio / 2, y + mPadding + mRadio, mRadio, mSchemeBasicPaint);
canvas.drawText(calendar.getScheme(), x + mItemWidth - mPadding - mRadio, y + mPadding + mSchemeBaseLine, mTextPaint);
}
/** * 绘制文本 * @param canvas canvas * @param calendar 日历calendar * @param x 日历Card x起点坐标 * @param y 日历Card y起点坐标 * @param hasScheme 是不是标记的日期 * @param isSelected 是否选中 */
@Override
protected void onDrawText(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme, boolean isSelected) {
int cx = x + mItemWidth / 2;
int top = y - mItemHeight / 6;
if (isSelected) {//优先绘制选择的
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
mSelectTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10, mSelectedLunarTextPaint);
} else if (hasScheme) {//不然绘制具备标记的
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentMonth() ? mSchemeTextPaint : mOtherMonthTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10, mCurMonthLunarTextPaint);
} else {//最好绘制普通文本
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :
calendar.isCurrentMonth() ? mCurMonthTextPaint : mOtherMonthTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + y + mItemHeight / 10,
calendar.isCurrentDay() ? mCurDayLunarTextPaint :
calendar.isCurrentMonth() ? mCurMonthLunarTextPaint : mOtherMonthLunarTextPaint);
}
}
/** * dp转px * * @param context context * @param dpValue dp * @return px */
private static int dipToPx(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
复制代码
public class MeizuWeekView extends WeekView {
private Paint mTextPaint = new Paint();
private Paint mSchemeBasicPaint = new Paint();
private float mRadio;
private int mPadding;
private float mSchemeBaseLine;
public MeizuWeekView(Context context) {
super(context);
mTextPaint.setTextSize(dipToPx(context, 8));
mTextPaint.setColor(0xffffffff);
mTextPaint.setAntiAlias(true);
mTextPaint.setFakeBoldText(true);
mSchemeBasicPaint.setAntiAlias(true);
mSchemeBasicPaint.setStyle(Paint.Style.FILL);
mSchemeBasicPaint.setTextAlign(Paint.Align.CENTER);
mSchemeBasicPaint.setColor(0xffed5353);
mSchemeBasicPaint.setFakeBoldText(true);
mRadio = dipToPx(getContext(), 7);
mPadding = dipToPx(getContext(), 4);
Paint.FontMetrics metrics = mSchemeBasicPaint.getFontMetrics();
mSchemeBaseLine = mRadio - metrics.descent + (metrics.bottom - metrics.top) / 2 + dipToPx(getContext(), 1);
}
/** * * @param canvas canvas * @param calendar 日历日历calendar * @param x 日历Card x起点坐标 * @param hasScheme hasScheme 非标记的日期 * @return true 则绘制onDrawScheme,由于这里背景色不是是互斥的 */
@Override
protected boolean onDrawSelected(Canvas canvas, Calendar calendar, int x, boolean hasScheme) {
mSelectedPaint.setStyle(Paint.Style.FILL);
mSelectedPaint.setColor(0x80cfcfcf);
canvas.drawRect(x + mPadding, mPadding, x + mItemWidth - mPadding, mItemHeight - mPadding, mSelectedPaint);
return true;
}
@Override
protected void onDrawScheme(Canvas canvas, Calendar calendar, int x) {
mSchemeBasicPaint.setColor(calendar.getSchemeColor());
canvas.drawCircle(x + mItemWidth - mPadding - mRadio / 2, mPadding + mRadio, mRadio, mSchemeBasicPaint);
canvas.drawText(calendar.getScheme(), x + mItemWidth - mPadding - mRadio, mPadding + mSchemeBaseLine, mTextPaint);
}
@Override
protected void onDrawText(Canvas canvas, Calendar calendar, int x, boolean hasScheme, boolean isSelected) {
int cx = x + mItemWidth / 2;
int top = -mItemHeight / 6;
if (isSelected) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
mSelectTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10, mSelectedLunarTextPaint);
} else if (hasScheme) {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentMonth() ? mSchemeTextPaint : mOtherMonthTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10, mCurMonthLunarTextPaint);
} else {
canvas.drawText(String.valueOf(calendar.getDay()), cx, mTextBaseLine + top,
calendar.isCurrentDay() ? mCurDayTextPaint :
calendar.isCurrentMonth() ? mCurMonthTextPaint : mOtherMonthTextPaint);
canvas.drawText(calendar.getLunar(), cx, mTextBaseLine + mItemHeight / 10,
calendar.isCurrentDay() ? mCurDayLunarTextPaint :
calendar.isCurrentMonth() ? mCurMonthLunarTextPaint : mOtherMonthLunarTextPaint);
}
}
/** * dp转px * * @param context context * @param dpValue dp * @return px */
private static int dipToPx(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
复制代码
app:month_view="com.haibin.calendarviewproject.meizu.MeiZuMonthView"
app:week_view="com.haibin.calendarviewproject.meizu.MeizuWeekView"
复制代码