The project needs to use the calendar control, this is our renderings.

Go to github searched a ha, search to dagod wrote CalendarView, all kinds of cool effect, I this kind of also need to customize the effect is ok, not much to say, directly open masturbation!

Gradle associated

Implementation 'com. Haibin: calendarview: 3.4.0'

use

Use it paid attention to in the first layout is < com. Haibin. Calendarview. Calendarview / > is the path of the package name, if direct is < calendarview / > is a system used to own a calendar control.

<com.haibin.calendarview.CalendarView
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Copy the code

Can directly preview the effect of some property configuration items: App :month_view_show_mode=”mode_fix” Sets the display mode for the monthly view. App: current_month_TEXt_color =”#212121″ Specifies the font color for the month of the current page App :other_month_text_color=”# CCCCCC” Of course to implement their own effect, those attributes are not enough, we need to customize MonthView to implement (project address also have demo can download reference).

Customize the MonthView

Custom MyMonthView class inherits from MonthView, add the property app to the XML layout :month_view=”com.calendar.MyMonthView”, here is the path of their own actual project MonthView, We need to draw the calendar ourselves.

/ / cancel the calendar bold mCurMonthTextPaint. SetFakeBoldText (false);
mOtherMonthTextPaint.setFakeBoldText(false);

Copy the code

TextStyle =”bold” setFakeBoldText(true) is less bold than the android:textStyle=”bold” attribute

Draw in onDrawText, the normal style calendar will display the time normally

@Override
protected void onDrawText(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme, boolean isSelected) {
    float baselineY = mTextBaseLine + y;
    int cx = x + mItemWidth / 2;
    int cy = y + mItemHeight / 2;
    canvas.drawText(String.valueOf(calendar.getDay()), cx, baselineY, calendar.isCurrentMonth() ? mCurMonthTextPaint : mOtherMonthTextPaint);
}

Copy the code

Here we need several types of styles to categorize:

1. Impossible

2. It can be done

3. What has been done today

History is done

Emulated data, distinguishing styles through scheme tags

Calendar calendar1 = getSchemeCalendar(2018, 8, 11, "1");
Calendar calendar2 = getSchemeCalendar(2018, 8, 12, "2");
Calendar calendar3 = getSchemeCalendar(2018, 8, 13, "3");
Calendar calendar4 = getSchemeCalendar(2018, 8, 6, "4");

map.put(calendar1.toString(), calendar1);
map.put(calendar2.toString(), calendar2);
map.put(calendar3.toString(), calendar3);
map.put(calendar4.toString(), calendar4);
calendarView.setSchemeDate(map);

private Calendar getSchemeCalendar(int year, int month, int day, String text) {
    Calendar calendar = new Calendar();
    calendar.setYear(year);
    calendar.setMonth(month);
    calendar.setDay(day);
    calendar.setScheme(text);
    return calendar;
}

Copy the code

Initialize two paints. The one with two image resources is drawn using a Bitmap

paint1.setColor(ContextCompat.getColor(context, R.color.green));
paint1.setTextSize(DensityUtil.spToPx(context, 13));
paint1.setStyle(Paint.Style.STROKE);
paint1.setAntiAlias(true);
paint1.setTextAlign(Paint.Align.CENTER);

paint2.setColor(ContextCompat.getColor(context, R.color.white));
paint2.setTextSize(DensityUtil.spToPx(context, 13));
paint2.setAntiAlias(true);
paint2.setTextAlign(Paint.Align.CENTER);

dayBgBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.day_bg);
daySuccessBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.day_success);

Copy the code

Main method onDrawText, according to different scheme to draw each view

@Override protected void onDrawText(Canvas canvas, Calendar calendar, int x, int y, boolean hasScheme, Boolean isSelected) {// where x and y are the starting coordinates of the dayfloat baselineY = mTextBaseLine + y;
    int cx = x + mItemWidth / 2;
    int cy = y + mItemHeight / 2;
    if ("1".equals(calendar.getScheme())) {// Not complete, draw circle paint1.setstrokeWidth (0); canvas.drawText(String.valueOf(calendar.getDay()), cx, baselineY, paint1); paint1.setStrokeWidth(DensityUtil.dpToPx(context, 1)); canvas.drawCircle(cx, cy + 3, mItemWidth / 4 - 9, paint1); }else if ("2".equals(calendar.getScheme())) {// Can be done, DrawText (String.valueof (calendar.getDay()), cx, baselineY, paint2); drawText(String.valueof (calendar.getday ()), cx, baselineY, paint2) canvas.drawBitmap(dayBgBitmap, x + mItemWidth / 4 - 5, y + mItemHeight / 4 + 8, paint2); }else if ("3".equals(calendar.getScheme())) {paint1.setstrokeWidth (0); canvas.drawText(String.valueOf(calendar.getDay()), cx, baselineY, paint1); paint1.setStrokeWidth(DensityUtil.dpToPx(context, 1)); canvas.drawCircle(cx, cy + 3, mItemWidth / 4 - 9, paint1); canvas.drawBitmap(daySuccessBitmap, x + mItemWidth * 3 / 4 - 18, y + mItemHeight * 3 / 4 - 24, paint1); }else if ("4".equals(calendar.getScheme())) {// History completed, draw checkbox picture paint1.setstrokeWidth (0); canvas.drawText(String.valueOf(calendar.getDay()), cx, baselineY, paint1); canvas.drawBitmap(daySuccessBitmap, x + mItemWidth * 3 / 4 - 18, y + mItemHeight * 3 / 4 - 40, paint1); }else{// Canvas. DrawText (string.valueof (calendar.getDay())), cx, baselineY, calendar.isCurrentMonth()? mCurMonthTextPaint : mOtherMonthTextPaint); }}Copy the code

The view is now drawn.

Next, complete the basic API calls.

API call

Initialize assigns the current month and year, and the time changes when the calendar is switched.

// Initialize the calendar month. SetText (calendarView.getCuryear () +"Year" + calendarView.getCurMonth() + "Month"); / / in switch change events calendarView. SetOnMonthChangeListener (new calendarView.OnMonthChangeListener() {
    @Override
    public void onMonthChange(int year, int month) {
        tvMonth.setText(year + "Year" + month + "Month"); }});Copy the code

There is a time picker in the layout, which is used to select the date and year. Here we use the Android-PickerView time picker.

/ / the time selector to choose, the corresponding calendar to switch to the specified date picker. SetOnClickListener (new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        TimePickerView pvTime = new TimePickerBuilder(MainActivity.this, new OnTimeSelectListener() { @Override public void onTimeSelect(Date date, View v) { java.util.Calendar c = java.util.Calendar.getInstance(); c.setTime(date); int year = c.get(java.util.Calendar.YEAR); int month = c.get(java.util.Calendar.MONTH); / / scroll to specified date calendarView. ScrollToCalendar (year, month + 1, 1); } }).setType(type).build(); pvTime.show(); }});Copy the code

Date selection listens for events

calendarView.setOnDateSelectedListener(new CalendarView.OnDateSelectedListener() {
    @Override
    public void onDateSelected(Calendar calendar, boolean isClick) {

    }
});

Copy the code

Of course, the effect drawing in different projects is different. As long as the basic drawing of canvas can achieve the desired effect.

See the detailed code can look for me to discuss or comment oh