简单自定义日历控件

简单自定义日历控件

布局文件中引用

<com.kun.arno.test.test.ArnoCalendarView
        android:id="@+id/arno_calendar_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

简单创建日历控件实例

        new ArnoCalendarView.Builder(this)
                .setPreviousPic(R.drawable.ic_launcher)
                .setNextPic(R.mipmap.ic_launcher)
                .setIsDivision(true)
                .setIsShowLunar(true)
                .setLanguageStyle(ArnoCalendarView.LANGUAGE_CHINA)
                .create();

简单创建日历PopupWindow

        new ArnoCalendarView.Builder(this)
                .setIsDivision(true)
                .setIsShowLunar(true)
                .setCalendarViewSelectedStyle(ArnoCalendarView.HOLLOW_CIRCLE)
                .setCalendarSelectedBackgroundStyleColor(Color.parseColor("#1571FA"))
                .setCalendarFestivalFontColor(Color.parseColor("#1571FA"))
                .setTitleBackgroundColor(Color.parseColor("#1571FA"))
                .setWeekDaysBackgroundColor(Color.parseColor("#1571FA"))
                .setWeekTypefaceInterceptor(new ArnoCalendarView.WeekTypefaceInterceptor() {
                    @Override
                    public int intercept(int index) {
                        return (index == 0|| index == 6) ? Color.parseColor("#000000") : Color.parseColor("#ffffff");
                    }
                })
                .createPopupWindow(new ArnoCalendarView.OnPopupWindowDateClickListener() {
                    @Override
                    public void onPopupWindowDateClick(PopupWindow popupWindow, int year, int month, int day) {

                    }
                }).showAtLocation(view, Gravity.CENTER, 0, 0);

简单创建日历Dialog

        new ArnoCalendarView.Builder(this)
                .setPreviousPic(R.drawable.ic_launcher)
                .setNextPic(R.mipmap.ic_launcher)
                .setIsDivision(true)
                .setIsShowLunar(true)
                .setLanguageStyle(ArnoCalendarView.LANGUAGE_CHINA)
                .createDialog(new ArnoCalendarView.OnDialogDateClickListener() {
                    @Override
                    public void onDialogDateClick(Dialog dialog, int year, int month, int day) {
                        
                    }
                }).show();

默认效果 

实现代码逻辑

package com.kun.arno.test.test;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.ColorDrawable;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;

import static android.view.View.MeasureSpec.getSize;


/**
 * @author Arno
 * @date 2018/8/8 0030
 * @des 1900-2049
 */

public class ArnoCalendarView extends LinearLayout {


    private static final String[] WEEK_CHINA = new String[]{"日", "一", "二", "三", "四", "五", "六"};

    private static final String[] WEEK_ENGLISH = new String[]{"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

    private static final String[] MONTH_ENGLISH = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

    private static final int THE_LAST_STYLE = -1;

    private static final int THE_CURRENT_STYLE = 0;

    private static final int THE_NEXT_STYLE = 1;

    private Builder builder;
    private Adapter adapter;

    private OnDateClickListener onDateClickListener;

    public void setOnDateClickListener(OnDateClickListener dateClick) {
        this.onDateClickListener = dateClick;
    }

    private ArnoCalendarView(Builder builder) {
        super(builder.context);
        this.builder = builder;
        this.initialize(builder.context);
    }

    private ArnoCalendarView(Context context) {
        this(context, null);
    }

    public ArnoCalendarView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.initialize(context);
    }

    private void initialize(Context context) {
        this.setOrientation(LinearLayout.VERTICAL);
        TitleView titleView = new TitleView(context);
        this.addView(titleView);
        this.addView(new WeekView(context));
        this.adapter = new Adapter(titleView);
        this.addView(new CalendarPager(context, adapter));
    }

    /**
     * 适配器
     */
    class Adapter extends PagerAdapter implements ViewPager.OnPageChangeListener {
        int currentItem = 0;
        List<MonthDateView> list = null;
        ViewPager viewPager;
        TitleView titleView;

        public void attachTo(ViewPager viewPager) {
            this.viewPager = viewPager;
            viewPager.setAdapter(this);
            currentItem = (Calendar.getInstance().get(Calendar.YEAR) - 1900) * 12 - 11 + Calendar.getInstance().get(Calendar.MONTH);
            viewPager.setCurrentItem(currentItem);
            initPosition(currentItem);
            viewPager.addOnPageChangeListener(this);

        }

        @Override
        public void notifyDataSetChanged() {
            super.notifyDataSetChanged();
            MonthDateView monthDateView = list.get(getPosition(viewPager.getCurrentItem()));
            if (builder.language == LANGUAGE_CHINA) {
                titleView.setTitleText(String.format("%s年%s月", monthDateView.getmSelYear(), monthDateView.getmSelMonth() + 1));
            } else {
                titleView.setTitleText(MONTH_ENGLISH[monthDateView.getmSelMonth()] + "\u3000" + monthDateView.getmSelYear());
            }
        }

        private void initPosition(int position) {
            Calendar calendar = Calendar.getInstance();
            if (builder.language == LANGUAGE_CHINA) {
                titleView.setTitleText(String.format("%s年%s月", calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1));
            } else {
                titleView.setTitleText(MONTH_ENGLISH[calendar.get(Calendar.MONTH)] + "\u3000" + calendar.get(Calendar.YEAR));
            }
            list.get(getPosition(currentItem)).setSelectYearMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE));
            list.get(getPosition(currentItem + 1)).setSelectYearMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE)).onRightClick();
            list.get(getPosition(currentItem - 1)).setSelectYearMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE)).onLeftClick();
        }

        Adapter(TitleView titleView) {
            this.titleView = titleView;
            list = new ArrayList<>();
            list.add(new MonthDateView(getContext()));
            list.add(new MonthDateView(getContext()));
            list.add(new MonthDateView(getContext()));
            list.add(new MonthDateView(getContext()));
            titleView.setLeftImageChecked(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (viewPager != null) {
                        viewPager.setCurrentItem(viewPager.getCurrentItem() + THE_LAST_STYLE);
                    }
                }
            }).setRightImageChecked(new OnClickListener() {
                @Override
                public void onClick(View view) {
                    if (viewPager != null) {
                        viewPager.setCurrentItem(viewPager.getCurrentItem() + THE_NEXT_STYLE);
                    }
                }
            });
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            //删除页卡
            container.removeView(list.get(getPosition(position)));
        }

        @Override
        public int getCount() {
            return 1788;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        @Override
        public Object instantiateItem(final ViewGroup view, int position) {
            MonthDateView monthDateView = list.get(getPosition(position));
            //如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。
            if (view != null) {
                view.removeView(monthDateView);
            }
            monthDateView.setOnMonthChangeListener(new OnMonthChangeListener() {
                @Override
                public void onMonthChange(int state) {
                    viewPager.setCurrentItem(viewPager.getCurrentItem() + state);
                }
            });
            view.addView(monthDateView);
            return monthDateView;
        }

        /**
         * 对ViewPager页号求模取出View列表中要显示的项
         *
         * @param position
         * @return
         */
        private int getPosition(int position) {
            position = (position - currentItem) % 4;
            if (position < 0) {
                position = 4 + position;
            }
            return position;
        }

        @Override
        public int getItemPosition(Object object) {
            // 最简单解决 notifyDataSetChanged() 页面不刷新问题的方法
            return POSITION_NONE;
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            if (currentItem == position) {
                initPosition(position);
            } else {
                MonthDateView monthDateView = list.get(getPosition(position));
                int years = monthDateView.getmSelYear();
                int month = monthDateView.getmSelMonth();
                int day = 1;
                if (builder.language == LANGUAGE_CHINA) {
                    if (builder.isShowLunar) {
                        titleView.setTitleText(String.format("%s年%s月", years, month + 1));
                    } else {
                        titleView.setTitleText(String.format("%s年%s月", years, month + 1));
                    }
                } else {
                    titleView.setTitleText(MONTH_ENGLISH[month] + "\u3000" + years);
                }
                if (monthDateView != null) {
                    list.get(getPosition(position + 1)).setSelectYearMonth(years, month, day).onRightClick();
                    list.get(getPosition(position - 1)).setSelectYearMonth(years, month, day).onLeftClick();
                }
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    }

    /**
     * 控件标题
     */
    class TitleView extends RelativeLayout {
        private final TextView textView;
        private final ImageView leftImageView;
        private final ImageView rightImageView;

        public TitleView(Context context) {
            super(context);
            textView = new TextView(context);

            LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
            this.addView(textView, layoutParams);
            leftImageView = new ImageView(context);
            rightImageView = new ImageView(context);

            LayoutParams leftLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
            leftLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            LayoutParams rightLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
            rightLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

            leftImageView.setImageResource(builder.previousPic);
            rightImageView.setImageResource(builder.nextPic);

            int padding = dp2px(5);

            leftImageView.setPadding(leftImageView.getLeft() + padding, leftImageView.getTop() + padding, leftImageView.getRight() + padding, leftImageView.getBottom() + padding);
            rightImageView.setPadding(rightImageView.getLeft() + padding, rightImageView.getTop() + padding, rightImageView.getRight() + padding, rightImageView.getBottom() + padding);
            this.addView(leftImageView, leftLayoutParams);
            this.addView(rightImageView, rightLayoutParams);

            this.textView.setTextColor(builder.titleFontColor);
            this.setBackgroundColor(builder.titleBackgroundColor);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int fourThreeHeight = MeasureSpec.makeMeasureSpec(getSize(widthMeasureSpec) / 7, MeasureSpec.EXACTLY);
            super.onMeasure(widthMeasureSpec, fourThreeHeight);
            leftImageView.getLayoutParams().width = getSize(fourThreeHeight);
            rightImageView.getLayoutParams().width = getSize(fourThreeHeight);
        }

        public TitleView setTitleText(String title) {
            textView.setText(title);
            return this;
        }

        public TitleView setLeftImageChecked(OnClickListener onClickListener) {
            leftImageView.setOnClickListener(onClickListener);
            return this;
        }

        public TitleView setRightImageChecked(OnClickListener onClickListener) {
            rightImageView.setOnClickListener(onClickListener);
            return this;
        }
    }

    /**
     * viewpager 显示月历
     */
    class CalendarPager extends ViewPager {
        public CalendarPager(Context context, Adapter adapter) {
            super(context);
            adapter.attachTo(this);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int fourThreeHeight = MeasureSpec.makeMeasureSpec(getSize(widthMeasureSpec) * 6 / 7, MeasureSpec.EXACTLY);
            super.onMeasure(widthMeasureSpec, fourThreeHeight);
        }
    }

    /**
     * 星期
     */
    class WeekView extends View {

        private final Paint paint;

        public WeekView(Context context) {
            super(context);
            this.setBackgroundColor(builder.weekDaysBackgroundColor);
            paint = new Paint();
            paint.setColor(builder.weekDaysFontColor);
            paint.setStyle(Paint.Style.FILL);
            paint.setStrokeWidth(20f);
            paint.setTextSize(sp2px(12));
        }

        @Override
        protected void onMeasure(int widthSpec, int heightSpec) {
            int fourThreeHeight = MeasureSpec.makeMeasureSpec(getSize(widthSpec) * 3 / 28, MeasureSpec.EXACTLY);
            super.onMeasure(widthSpec, fourThreeHeight);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            int height = getHeight();
            int columnWidth = getWidth() / 7;
            for (int i = 0; i < WEEK_CHINA.length; i++) {
                String text = "err";
                switch (builder.language) {
                    case LANGUAGE_CHINA:
                        text = WEEK_CHINA[i];
                        break;
                    case LANGUAGE_ENGLISH:
                        text = WEEK_ENGLISH[i];
                        break;
                    default:
                        break;
                }
                try {
                    paint.setColor(intercept(i));
                } catch (Exception e) {
                    paint.setColor(builder.weekDaysFontColor);
                }
                int fontWidth = (int) paint.measureText(text);
                int startX = columnWidth * i + (columnWidth - fontWidth) / 2;
                int startY = (int) (height / 2 - (paint.ascent() + paint.descent()) / 2);
                canvas.drawText(text, startX, startY, paint);
            }
        }

        /**
         * 星期栏字体颜色拦截
         *
         * @param index
         * @return
         */
        public int intercept(int index) throws Exception {
            if (null != builder.weekTypefaceInterceptor) {
                return builder.weekTypefaceInterceptor.intercept(index);
            } else {
                return builder.weekDaysFontColor;
            }
        }
    }

    /**
     * 月历
     */
    class MonthDateView extends View {

        private int mSelYear, mSelMonth, mSelDay;
        private int mColumnSize, mRowSize;
        private int[][] daysString;
        private int selectData = -1;

        public MonthDateView(Context context) {
            this(context, null);
        }

        public MonthDateView(Context context, AttributeSet attrs) {
            super(context, attrs);
            Calendar calendar = Calendar.getInstance();
            setSelectYearMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE));
            this.setBackgroundColor(builder.calendarBackgroundColor);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            initSize();
            daysString = new int[6][7];
            int mMonthDays = getMonthDays(mSelYear, mSelMonth);
            int weekNumber = getFirstDayWeek(mSelYear, mSelMonth) - 1;
            int start = weekNumber == 0 ? 7 : weekNumber;

            for (int day = 0, size = 42; day < size; day++) {
                int column = day % 7;
                int row = day / 7;

                if (day < start) {
                    daysString[row][column] = -1;
                    canvasDrawText(canvas, getIsCurrentCalendar(mSelYear, mSelMonth, 1, THE_LAST_STYLE).getActualMaximum(Calendar.DATE) + day - start + 1, column, row, THE_LAST_STYLE);
                } else if (day >= start && day < mMonthDays + start) {
                    daysString[row][column] = day + 1 - start;
                    canvasDrawText(canvas, day - start + 1, column, row, THE_CURRENT_STYLE);
                } else {
                    daysString[row][column] = -2;
                    canvasDrawText(canvas, day - start - mMonthDays + 1, column, row, THE_NEXT_STYLE);
                }
            }
        }


        /**
         * @param canvas
         * @param day
         * @param column
         * @param row
         * @param style
         */
        private void canvasDrawText(Canvas canvas, int day, int column, int row, int style) {

            //样式是否实心样式
            boolean isSolid = builder.calendarSelectedStyle == SOLID_CIRCLE || builder.calendarSelectedStyle == SOLID_RECTANGLE;
            //是否溢出日期
            boolean isOverflow = style != THE_CURRENT_STYLE;
            //是否是当天
            boolean isToday = isCurrentDate(mSelYear, mSelMonth) == day && !isOverflow;
            //是否选择
            boolean isSelected = (day == selectData) && !isToday && !isOverflow;
            //是否屏蔽边框
            boolean isShieldBorder = !(isSelected && column != 0 && column != 6);

            if (isSelected) {
                switch (builder.calendarSelectedStyle) {
                    case SOLID_CIRCLE:
                        canvasSolidCircle(canvas, column, row);
                        break;
                    case SOLID_RECTANGLE:
                        canvasSolidRect(canvas, column, row);
                        break;
                    case HOLLOW_CIRCLE:
                        canvasHollowCircle(canvas, column, row);
                        break;
                    case HOLLOW_RECTANGLE:
                        canvasHollowRect(canvas, column, row);
                        break;
                    default:
                        break;
                }
            }
            //添加边框
            if (builder.isDivision && isShieldBorder) {
                canvasDrawingLine(canvas, column, row);
            }
            if (isToday) {
                canvasSolidCircle(canvas, column, row);
            }
            Paint solarPaint = new Paint();
            solarPaint.setStrokeWidth(10f);
            solarPaint.setTextSize(mRowSize * 0.4f);

            if (builder.isShowLunar) {
                Paint lunarPaint = new Paint();
                lunarPaint.setColor(builder.calendarOverflowColor);
                lunarPaint.setStrokeWidth(10f);
                lunarPaint.setTextSize(mRowSize * 0.2f);
                solarPaint.setTextSize(mRowSize * 0.3f);
                String lunar = lunarSolar(getIsCurrentCalendar(mSelYear, mSelMonth, day, style));
                boolean isFestival = !lunar.contains("初") && !lunar.contains("十") && !lunar.contains("廿") && !lunar.contains("卅");
                solarPaint.setColor(isOverflow ? builder.calendarOverflowColor : isToday ? builder.calendarSelectedFontStyleColor : (isSelected ? (isSolid ? builder.calendarSelectedFontStyleColor : builder.calendarFontColor) : builder.calendarFontColor));
                lunarPaint.setColor(isOverflow ? builder.calendarOverflowColor : isToday ? builder.calendarSelectedFontStyleColor : (isSelected ? (isSolid ? builder.calendarSelectedFontStyleColor : isFestival ? builder.calendarFestivalFontColor : builder.calendarOverflowColor) : (isFestival ? builder.calendarFestivalFontColor : builder.calendarOverflowColor)));

                int startY1 = (int) (mRowSize * row + (mRowSize * 0.6 - solarPaint.ascent() - solarPaint.descent()) * 2 / 3);
                int startX1 = (int) (mColumnSize * column + (mColumnSize - solarPaint.measureText(day + "")) / 2);
                canvas.drawText(day + "", startX1, startY1, solarPaint);
                int startY2 = (int) (mRowSize * row + mRowSize * 0.6 + (mRowSize * 0.4 - lunarPaint.ascent() - lunarPaint.descent()) / 3);
                int startX2 = (int) (mColumnSize * column + (mColumnSize - lunarPaint.measureText(lunar)) / 2);
                canvas.drawText(lunar, startX2, startY2, lunarPaint);
            } else {
                int startY1 = (int) (mRowSize * row + (mRowSize - solarPaint.ascent() - solarPaint.descent()) * 0.5f);
                int startX1 = (int) (mColumnSize * column + (mColumnSize - solarPaint.measureText(day + "")) * 0.5f);
                solarPaint.setColor(isOverflow ? builder.calendarOverflowColor : isToday ? builder.calendarSelectedFontStyleColor : (isSelected ? (isSolid ? builder.calendarSelectedFontStyleColor : builder.calendarFontColor) : builder.calendarFontColor));
                canvas.drawText(day + "", startX1, startY1, solarPaint);
            }
        }

        /**
         * 绘制 格子 边框
         *
         * @param canvas
         * @param column
         * @param row
         */
        private void canvasDrawingLine(Canvas canvas, int column, int row) {
            Path boxPath = new Path();
            boxPath.moveTo(mColumnSize * column, mRowSize * row);
            boxPath.lineTo(mColumnSize * (column + 1), mRowSize * row);
            boxPath.lineTo(mColumnSize * (column + 1), mRowSize * (row + 1));
            boxPath.lineTo(mColumnSize * column, mRowSize * (row + 1));
            boxPath.close();
            //边框
            Paint borderPaint = new Paint();
            borderPaint.setStyle(Paint.Style.STROKE);
            borderPaint.setStrokeWidth(2f);
            borderPaint.setColor(builder.calendarSegmentationLineColor);
            canvas.drawPath(boxPath, borderPaint);
        }

        /**
         * 绘制空心矩形
         *
         * @param canvas
         * @param column
         * @param row
         */
        private void canvasHollowRect(Canvas canvas, int column, int row) {
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(builder.calendarSelectedBackgroundStyleColor);
            canvas.drawRect(mColumnSize * column, mRowSize * row, mColumnSize * column + mColumnSize, mRowSize * row + mRowSize, paint);
            canvas.drawCircle(mColumnSize * column + mColumnSize * 0.5f, mRowSize * row + mRowSize * 0.5f, mColumnSize * 0.5f, paint);
            paint.setColor(builder.calendarBackgroundColor);
            canvas.drawRect(mColumnSize * column + dp2px(2), mRowSize * row + dp2px(2), mColumnSize * column + mColumnSize - dp2px(2), mRowSize * row + mRowSize - dp2px(2), paint);
        }

        /**
         * 绘制实心矩形
         *
         * @param canvas
         * @param column
         * @param row
         */
        private void canvasSolidRect(Canvas canvas, int column, int row) {
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(builder.calendarSelectedBackgroundStyleColor);
            canvas.drawRect(mColumnSize * column, mRowSize * row, mColumnSize * column + mColumnSize, mRowSize * row + mRowSize, paint);
        }

        /**
         * 绘制空心圆
         *
         * @param canvas
         * @param column
         * @param row
         */
        private void canvasHollowCircle(Canvas canvas, int column, int row) {
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(builder.calendarSelectedBackgroundStyleColor);
            canvas.drawCircle(mColumnSize * column + mColumnSize * 0.5f, mRowSize * row + mRowSize * 0.5f, mColumnSize * 0.5f, paint);
            paint.setColor(builder.calendarBackgroundColor);
            canvas.drawCircle(mColumnSize * column + mColumnSize * 0.5f, mRowSize * row + mRowSize * 0.5f, mColumnSize * 0.5f - dp2px(2), paint);
        }

        /**
         * 绘制实心圆
         *
         * @param canvas
         * @param column
         * @param row
         */
        private void canvasSolidCircle(Canvas canvas, int column, int row) {
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(builder.calendarSelectedBackgroundStyleColor);
            canvas.drawCircle(mColumnSize * column + mColumnSize * 0.5f, mRowSize * row + mRowSize * 0.5f, mColumnSize * 0.5f, paint);
        }

        private int downX = 0, downY = 0;

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int eventCode = event.getAction();
            switch (eventCode) {
                case MotionEvent.ACTION_DOWN:
                    downX = (int) event.getX();
                    downY = (int) event.getY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    break;
                case MotionEvent.ACTION_UP:
                    int upX = (int) event.getX();
                    int upY = (int) event.getY();
                    if (Math.abs(upX - downX) < 10 && Math.abs(upY - downY) < 10) {
                        performClick();
                        doClickAction((upX + downX) / 2, (upY + downY) / 2);
                    }
                    break;
                default:
                    break;
            }
            return true;
        }

        /**
         * 初始化列宽行高
         */
        private void initSize() {
            mColumnSize = getWidth() / 7;
            mRowSize = getHeight() / 6;
        }

        /**
         * 设置年月
         *
         * @param year
         * @param month
         */
        public MonthDateView setSelectYearMonth(int year, int month, int day) {
            mSelYear = year;
            mSelMonth = month;
            mSelDay = day;
            return this;
        }


        /**
         * 执行点击事件
         *
         * @param x
         * @param y
         */
        private void doClickAction(int x, int y) {
            int row = y / mRowSize;
            int column = x / mColumnSize;

            if (daysString[row][column] > 0) {
                selectData = daysString[row][column];
                invalidate();
                //执行发送过来的点击处理事件
                if (onDateClickListener != null) {
                    onDateClickListener.onDateClick(mSelYear, mSelMonth, daysString[row][column]);
                }
            } else if (onMonthChangeListener != null) {
                switch (daysString[row][column]) {
                    case -1:
                        onMonthChangeListener.onMonthChange(THE_LAST_STYLE);
                        break;
                    case -2:
                        onMonthChangeListener.onMonthChange(THE_NEXT_STYLE);
                        break;
                    default:
                        break;
                }
            }
        }

        /**
         * 左点击,日历向后翻页
         */
        public void onLeftClick() {
            Calendar calendar = getIsCurrentCalendar(mSelYear, mSelMonth, 1, -1);
            setSelectYearMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1);
            invalidate();
        }

        /**
         * 右点击,日历向前翻页
         */
        public void onRightClick() {
            Calendar calendar = getIsCurrentCalendar(mSelYear, mSelMonth, 1, +1);
            setSelectYearMonth(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1);
            invalidate();
        }

        /**
         * 获取选择的年份
         *
         * @return
         */
        public int getmSelYear() {
            return mSelYear;
        }

        /**
         * 获取选择的月份
         *
         * @return
         */
        public int getmSelMonth() {
            return mSelMonth;
        }

        /**
         * 获取选择的日期
         */
        public int getmSelDay() {
            return this.mSelDay;
        }


        private OnMonthChangeListener onMonthChangeListener;

        public void setOnMonthChangeListener(OnMonthChangeListener onMonthChangeListener) {
            this.onMonthChangeListener = onMonthChangeListener;
        }
    }
    /***********************************日期改变事件*********************************************/
    /**
     * 设置日期的点击回调事件
     *
     * @author shiwei.deng
     */
    public interface OnDateClickListener {
        /**
         * 执行点击事件
         *
         * @param year
         * @param month
         * @param day
         */
        void onDateClick(int year, int month, int day);
    }

    /**
     * 设置日期的点击回调事件
     *
     * @author shiwei.deng
     */
    public interface OnPopupWindowDateClickListener {
        /**
         * popupWindow回调事件
         *
         * @param popupWindow
         * @param year
         * @param month
         * @param day
         */
        void onPopupWindowDateClick(PopupWindow popupWindow, int year, int month, int day);
    }

    /**
     * 设置日期的点击回调事件
     *
     * @author shiwei.deng
     */
    public interface OnDialogDateClickListener {
        /**
         * Dialog回调事件
         *
         * @param dialog
         * @param year
         * @param month
         * @param day
         */
        void onDialogDateClick(Dialog dialog, int year, int month, int day);
    }

    /**
     * 设置日期的改变事件 Month change event
     *
     * @author shiwei.deng
     */
    public interface OnMonthChangeListener {
        /**
         * 切换月份事件
         *
         * @param state
         */
        void onMonthChange(int state);
    }
    /***********************************时间工具类*********************************************/

    /**
     * @param year
     * @param month 是否是当前月份
     * @return
     */
    private int isCurrentDate(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        if (calendar.get(Calendar.YEAR) == year && calendar.get(Calendar.MONTH) == month) {
            return calendar.get(Calendar.DATE);
        }
        return -1;
    }

    /**
     * @param year
     * @param month
     * @param day
     * @param isCurrent 是否是上个月,当前月,下个月
     * @return 返回上个月的,当月,下个月的  Calendar
     */
    private Calendar getIsCurrentCalendar(int year, int month, int day, int isCurrent) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, 1);
        if (isCurrent != 0) {
            calendar.add(Calendar.MONTH, +isCurrent);
        }
        calendar.set(Calendar.DATE, day);
        return calendar;
    }

    /**
     * 通过年份和月份 得到当月的日子
     *
     * @param year
     * @param month
     * @return
     */
    public int getMonthDays(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, 1);
        calendar.roll(Calendar.DATE, -1);
        return calendar.get(Calendar.DATE);
    }

    /**
     * 返回当前月份1号位于周几
     *
     * @param year  年份
     * @param month 月份,传入系统获取的,不需要正常的
     * @return 日:1		一:2		二:3		三:4		四:5		五:6		六:7
     */
    private int getFirstDayWeek(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month, 1);
        Log.d("DateView", "DateView:First:" + calendar.getFirstDayOfWeek());
        return calendar.get(Calendar.DAY_OF_WEEK);
    }

    /**
     * dpתpx
     *
     * @return
     */
    private int dp2px(float dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, this.getContext().getResources().getDisplayMetrics());
    }

    /**
     * @param spVal
     * @return
     */
    private int sp2px(float spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                spVal, this.getContext().getResources().getDisplayMetrics());
    }

    /*******************************日历农历计算********************************************/


    static class LunarSolar {
        int solarYear;
        int solarMonth;
        int solarDate;

        int lunarYear;
        int lunarMonth;
        int lunarDate;

        String lunarHolidayName;
        String lunarDateName;
        String solarHolidayName;
        String to24TermStringName;

        public LunarSolar(int solarYear, int solarMonth, int solarDate, int lunarYear, int lunarMonth, int lunarDate, String lunarHolidayName, String lunarDateName, String solarHolidayName, String to24TermStringName) {
            this.solarYear = solarYear;
            this.solarMonth = solarMonth;
            this.solarDate = solarDate;
            this.lunarYear = lunarYear;
            this.lunarMonth = lunarMonth;
            this.lunarDate = lunarDate;
            this.lunarHolidayName = lunarHolidayName;
            this.lunarDateName = lunarDateName;
            this.solarHolidayName = solarHolidayName;
            this.to24TermStringName = to24TermStringName;
        }
    }


    private LunarSolar solarToLunar(Calendar calendar) {
        int year;
        int month;
        int day;
        boolean leap;
        @SuppressWarnings(" unused ")
        int yearCyl, monCyl, dayCyl;
        int leapMonth = 0;
        Date baseDate = null;
        try {
            baseDate = CHINESE_DATE_FORMAT.parse(" 1900年1月31日 ");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 求出和1900年1月31日相差的天数
        int offset = (int) ((calendar.getTime().getTime() - baseDate.getTime()) / 86400000L);
        dayCyl = offset + 40;
        monCyl = 14;
        // 用offset减去每农历年的天数// 计算当天是农历第几天// i最终结果是农历的年份// offset是当年的第几天
        int iYear, daysOfYear = 0;
        for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
            daysOfYear = yearDays(iYear);
            offset -= daysOfYear;
            monCyl += 12;
        }
        if (offset < 0) {
            offset += daysOfYear;
            iYear--;
            monCyl -= 12;
        }
        // 农历年份
        year = iYear;
        yearCyl = iYear - 1864;
        // 闰哪个月,1-12
        leapMonth = leapMonth(iYear);
        leap = false;
        // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
        int iMonth, daysOfMonth = 0;
        for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
            // 闰月
            if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
                --iMonth;
                leap = true;
                daysOfMonth = leapDays(year);
            } else {
                daysOfMonth = monthDays(year, iMonth);
            }

            offset -= daysOfMonth;
            // 解除闰月
            if (leap && iMonth == (leapMonth + 1)) {
                leap = false;
            }
            if (!leap) {
                monCyl++;
            }
        }
        // offset为0时,并且刚才计算的月份是闰月,要校正
        if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
            if (leap) {
                leap = false;
            } else {
                leap = true;
                --iMonth;
                --monCyl;
            }
        }
        // offset小于0时,也要校正
        if (offset < 0) {
            offset += daysOfMonth;
            --iMonth;
            --monCyl;
        }
        month = iMonth;
        day = offset + 1;

        LunarSolar lunarSolar = new LunarSolar(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE),
                year, month, day,
                getLunarHoliday(year, month, day),
                getChinaDayString(day),
                getSolarHoliday(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.DATE)),
                getTermString(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE))
        );
        return lunarSolar;

    }

    private String lunarSolar(Calendar calendar) {
        LunarSolar lunarSolar = solarToLunar(calendar);
        if (!TextUtils.isEmpty(lunarSolar.to24TermStringName)) {
            return lunarSolar.to24TermStringName;
        }
        if (!TextUtils.isEmpty(lunarSolar.solarHolidayName)) {
            return lunarSolar.solarHolidayName;
        }
        if (!TextUtils.isEmpty(lunarSolar.lunarHolidayName)) {
            return lunarSolar.lunarHolidayName;
        }
        if (!TextUtils.isEmpty(lunarSolar.lunarHolidayName)) {
            return lunarSolar.lunarHolidayName;
        }
        return lunarSolar.lunarDateName;
    }


    /**
     * // ====== 传回农历 y年的总天数
     *
     * @param y
     * @return
     */
    final private int yearDays(int y) {
        int i, sum = 348;
        for (i = 0x8000; i > 0x8; i >>= 1) {
            if ((LUNAR_INFO[y - 1900] & i) != 0) {
                sum += 1;
            }
        }
        return (sum + leapDays(y));
    }

    /**
     * // ====== 传回农历 y年闰月的天数
     *
     * @param y
     * @return
     */
    final private int leapDays(int y) {
        if (leapMonth(y) != 0) {
            if ((LUNAR_INFO[y - 1900] & 0x10000) != 0) {
                return 30;
            } else {
                return 29;
            }
        } else {
            return 0;
        }
    }

    /**
     * // ====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
     *
     * @param y
     * @return
     */
    final private int leapMonth(int y) {
        return (int) (LUNAR_INFO[y - 1900] & 0xf);
    }

    /**
     * // ====== 传回农历 y年m月的总天数
     *
     * @param y
     * @param m
     * @return
     */
    final private int monthDays(int y, int m) {
        if ((LUNAR_INFO[y - 1900] & (0x10000 >> m)) == 0) {
            return 29;
        } else {
            return 30;
        }
    }

    /**
     * @param day
     * @return
     */
    final private String getChinaDayString(int day) {
        String[] chineseTen =
                {"初", "十", "廿", "卅"};
        int n = day % 10 == 0 ? 9 : day % 10 - 1;
        if (day > 30) {
            return "";
        }
        if (day == 10) {
            return "初十";
        } else {
            return chineseTen[day / 10] + CHINESE_NUMBER[n];
        }
    }

    /**
     * 计算农历节日
     *
     * @param month
     * @param day
     * @return
     */
    final private String getSolarHoliday(int year, int month, int day) {

        int md = (int) (month * Math.pow(10, day >= 10 ? 2 : 1) + day);
        String holiday = "";
        switch (md) {
            case 11:
                holiday = "元旦";
                break;
            case 214:
                holiday = "情人节";
                break;
            case 38:
                holiday = "妇女节";
                break;
            case 312:
                holiday = "植树节";
                break;
            case 315:
                holiday = "消费者日";
                break;
            case 41:
                holiday = "愚人节";
                break;
            case 51:
                holiday = "劳动节";
                break;
            case 54:
                holiday = "青年节";
                break;
            case 59:
                holiday = "郝维节";
                break;
            case 512:
                holiday = "护士节";
                break;
            case 61:
                holiday = "儿童节";
                break;
            case 71:
                holiday = "建党节";
                break;
            case 81:
                holiday = "建军节";
                break;
            case 910:
                holiday = "教师节";
                break;
            case 928:
                holiday = "孔子诞辰";
                break;
            case 101:
                holiday = "国庆节";
                break;
            case 106:
                holiday = "老人节";
                break;
            case 1024:
                holiday = "联合国日";
                break;
            case 1111:
                holiday = "光棍节";
                break;
            case 1225:
                holiday = "圣诞节";
                break;
            default:
                break;
        }
        if (!TextUtils.isEmpty(holiday)) {
            return holiday;
        }
        if (month == 4 && day == chingMingDay(year, month)) {
            holiday = "清明节";
        } else if (month == 5 && day == motherFatherDay(year, month, 1)) {
            holiday = "母亲节";
        } else if (month == 6 && day == motherFatherDay(year, month, 2)) {
            holiday = "父亲节";
        }
        return holiday;
    }

    /**
     * 计算母亲节
     * 父亲节
     *
     * @param year
     * @param month
     * @param delta
     * @return
     */
    final private int motherFatherDay(int year, int month, int delta) {
        int f = getFirstDayWeek(year, month - 1);
        return 7 * delta + (f == 1 ? f : 9 - f);
    }

    /**
     * 计算清明节
     *
     * @param year
     * @param day
     * @return
     */
    final private int chingMingDay(int year, int day) {
        if (day >= 4 && day <= 6) {
            if (year <= 1999) {
                int compare = (int) (((year - 1900) * 0.2422 + 5.59) - ((year - 1900) / 4));
                if (compare == day) {
                    return compare;
                }
            } else {
                int compare = (int) (((year - 2000) * 0.2422 + 4.81) - ((year - 2000) / 4));
                if (compare == day) {
                    return compare;
                }
            }
        }
        return -1;
    }

    /**
     * 计算农历节日
     *
     * @param month
     * @param day
     * @return
     */
    final private String getLunarHoliday(int year, int month, int day) {
        int md = (int) (month * Math.pow(10, day >= 10 ? 2 : 1) + day);
        String holiday = "";
        boolean isNewYearsEve = month == 12 && ((day == 29 && (daysInLunarMonth(year, month) == 29))) || (((day == 30 && (daysInLunarMonth(year, month) == 30))));
        if (isNewYearsEve) {
            return holiday = "除夕";
        }
        switch (md) {
            case 11:
                holiday = "春节";
                break;
            case 115:
                holiday = "元宵节";
                break;
            case 22:
                holiday = "龙抬头";
                break;
            case 55:
                holiday = "端午节";
                break;
            case 77:
                holiday = "七夕";
                break;
            case 715:
                holiday = "中元节";
                break;
            case 815:
                holiday = "中秋节";
                break;
            case 99:
                holiday = "重阳节";
                break;
            case 1010:
                holiday = "祭祖节";
                break;
            case 128:
                holiday = "腊八节";
                break;
            case 1224:
                holiday = "小年";
                break;
            default:
                break;
        }
        return holiday;
    }

    /**
     * @param year
     * @param month
     * @return
     */
    final private int daysInLunarMonth(int year, int month) {
        if ((LUNAR_INFO[year - 1900] & (0x100000 >> month)) == 0) {
            return 29;
        } else {
            return 30;
        }
    }

    /**
     * 根据阳历日期计算24节气
     */
    private static GregorianCalendar utcCal = null;

    /**
     * 根据阳历日期计算24节气
     */
    public static String getTermString(int solarYear, int solarMonth, int solarDay) {
        String termString = "";
        if (getSolarTermDay(solarYear, solarMonth * 2) == solarDay) {
            termString = SOLAR_TERM[solarMonth * 2];
        } else if (getSolarTermDay(solarYear, solarMonth * 2 + 1) == solarDay) {
            termString = SOLAR_TERM[solarMonth * 2 + 1];
        }
        return termString;
    }

    private static int getSolarTermDay(int solarYear, int index) {
        return getUTCDay(getSolarTermCalendar(solarYear, index));
    }

    private static Date getSolarTermCalendar(int solarYear, int index) {
        long l = (long) 31556925974.7 * (solarYear - 1900)
                + SOLAR_TERM_INFO[index] * 60000L;
        l = l + utc(1900, 0, 6, 2, 5, 0);
        return new Date(l);
    }

    private static synchronized int getUTCDay(Date date) {
        makeUTCCalendar();
        synchronized (utcCal) {
            utcCal.clear();
            utcCal.setTimeInMillis(date.getTime());
            return utcCal.get(Calendar.DAY_OF_MONTH);
        }
    }

    private static void makeUTCCalendar() {
        if (utcCal == null) {
            utcCal = new GregorianCalendar(TimeZone.getTimeZone("utc"));
        }
    }

    static synchronized long utc(int y, int m, int d, int h, int min, int sec) {
        makeUTCCalendar();
        synchronized (utcCal) {
            utcCal.clear();
            utcCal.set(y, m, d, h, min, sec);
            return utcCal.getTimeInMillis();
        }
    }

    /**
     * 计算24节气结束
     */
    final static String[] CHINESE_NUMBER = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
    /**
     * 24 节气
     */
    static final String[] SOLAR_TERM = {
            "小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至",
            "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"};
    static final int[] SOLAR_TERM_INFO = {
            0, 21208, 42467, 63836, 85337, 107014, 128867, 150921,
            173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033,
            353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758
    };
    static final SimpleDateFormat CHINESE_DATE_FORMAT = new SimpleDateFormat(" yyyy年MM月dd日 ");

    static final long[] LUNAR_INFO = new long[]
            {0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0,
                    0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255,
                    0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0,
                    0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2,
                    0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60,
                    0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550,
                    0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
                    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0,
                    0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4,
                    0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0,
                    0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540,
                    0x0b5a0, 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a,
                    0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970,
                    0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5,
                    0x092e0, 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0,
                    0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4,
                    0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
                    0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0,
                    0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7,
                    0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0,
                    0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255,
                    0x06d20, 0x0ada0};


    public static final int LANGUAGE_CHINA = 1;
    public static final int LANGUAGE_ENGLISH = 2;

    public static final int SOLID_CIRCLE = 0;
    public static final int HOLLOW_CIRCLE = 1;
    public static final int SOLID_RECTANGLE = 2;
    public static final int HOLLOW_RECTANGLE = 3;


    @IntDef({LANGUAGE_CHINA, LANGUAGE_ENGLISH})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Language {

    }

    @IntDef({SOLID_CIRCLE, HOLLOW_CIRCLE, SOLID_RECTANGLE, HOLLOW_RECTANGLE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface CalendarSelectedStyle {
    }

    public interface WeekTypefaceInterceptor {
        /**
         * 拦截器
         *
         * @param index
         * @return
         */
        @ColorInt
        int intercept(int index);
    }

    /**
     * 构建
     */
    public static class Builder {
        private Context context = null;
        private int previousPic = android.R.drawable.ic_media_previous;
        private int nextPic = android.R.drawable.ic_media_next;
        private boolean isDivision = true;
        private boolean isShowLunar = true;

        private int titleBackgroundColor = Color.parseColor("#C3050A");
        private int titleFontColor = Color.WHITE;


        private int weekDaysBackgroundColor = Color.parseColor("#F87381");
        private int weekDaysFontColor = Color.WHITE;

        private int calendarBackgroundColor = Color.WHITE;
        private int calendarSegmentationLineColor = Color.parseColor("#C8C8C8");


        private int calendarFontColor = Color.BLACK;
        private int calendarFestivalFontColor = Color.parseColor("#6BC7A2");

        @CalendarSelectedStyle
        private int calendarSelectedStyle = ArnoCalendarView.SOLID_RECTANGLE;

        private int calendarSelectedBackgroundStyleColor = Color.parseColor("#6BC7A2");

        private int calendarSelectedFontStyleColor = Color.WHITE;

        private int calendarOverflowColor = Color.parseColor("#C8C8C8");

        @Language
        private int language = ArnoCalendarView.LANGUAGE_CHINA;


        private WeekTypefaceInterceptor weekTypefaceInterceptor;


        public Builder(Context context) {
            this.context = context;
        }

        /**
         * 上一月的图标
         *
         * @param previousPic
         * @return
         */
        public Builder setPreviousPic(@DrawableRes int previousPic) {
            this.previousPic = previousPic;
            return this;
        }

        /**
         * 下一月的图标
         *
         * @param nextPic
         * @return
         */
        public Builder setNextPic(@DrawableRes int nextPic) {
            this.nextPic = nextPic;
            return this;
        }

        /**
         * 节日字体颜色
         *
         * @param calendarFestivalFontColor
         * @return
         */
        public Builder setCalendarFestivalFontColor(int calendarFestivalFontColor) {
            this.calendarFestivalFontColor = calendarFestivalFontColor;
            return this;
        }

        /**
         * 选择日期背景颜色
         *
         * @param calendarSelectedBackgroundStyleColor
         * @return
         */
        public Builder setCalendarSelectedBackgroundStyleColor(int calendarSelectedBackgroundStyleColor) {
            this.calendarSelectedBackgroundStyleColor = calendarSelectedBackgroundStyleColor;
            return this;
        }

        /**
         * 星期栏背景颜色
         *
         * @param weekDaysBackgroundColor
         * @return
         */
        public Builder setWeekDaysBackgroundColor(int weekDaysBackgroundColor) {
            this.weekDaysBackgroundColor = weekDaysBackgroundColor;
            return this;
        }

        /**
         * 星期栏字体颜色
         *
         * @param weekDaysFontColor
         * @return
         */
        public Builder setWeekDaysFontColor(int weekDaysFontColor) {
            this.weekDaysFontColor = weekDaysFontColor;
            return this;
        }

        /**
         * 标题背景颜色
         *
         * @param titleBackgroundColor
         * @return
         */
        public Builder setTitleBackgroundColor(int titleBackgroundColor) {
            this.titleBackgroundColor = titleBackgroundColor;
            return this;
        }

        /**
         * 标题文字颜色
         *
         * @param titleFontColor
         * @return
         */
        public Builder setTitleFontColor(int titleFontColor) {
            this.titleFontColor = titleFontColor;
            return this;
        }

        /**
         * 选中日期的样式
         *
         * @param calendarSelectedStyle
         * @return
         */
        public Builder setCalendarViewSelectedStyle(@CalendarSelectedStyle int calendarSelectedStyle) {
            this.calendarSelectedStyle = calendarSelectedStyle;
            return this;
        }

        /**
         * 选择语言种类
         *
         * @param language
         * @return
         */
        public Builder setLanguageStyle(@Language int language) {
            this.language = language;
            return this;
        }

        /**
         * 是否显示边框
         *
         * @param division
         * @return
         */
        public Builder setIsDivision(boolean division) {
            this.isDivision = division;
            return this;
        }

        /**
         * 日期
         *
         * @param weekTypefaceInterceptor
         * @return
         */
        public Builder setWeekTypefaceInterceptor(WeekTypefaceInterceptor weekTypefaceInterceptor) {
            this.weekTypefaceInterceptor = weekTypefaceInterceptor;
            return this;
        }

        /**
         * 是否显示农历
         *
         * @param showLunar
         * @return
         */
        public Builder setIsShowLunar(boolean showLunar) {
            this.isShowLunar = showLunar;
            return this;
        }

        public ArnoCalendarView create() {
            return new ArnoCalendarView(this);
        }

        /**
         * 创建弹出框PopupWindow
         *
         * @param onPopupWindowDateClickListener
         * @return
         */
        public PopupWindow createPopupWindow(final OnPopupWindowDateClickListener onPopupWindowDateClickListener) {
            ArnoCalendarView kunCalendarView = create();
            final PopupWindow popupWindow = new PopupWindow(kunCalendarView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
            popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
            kunCalendarView.setOnDateClickListener(new OnDateClickListener() {
                @Override
                public void onDateClick(int year, int month, int day) {
                    if (onPopupWindowDateClickListener != null) {
                        onPopupWindowDateClickListener.onPopupWindowDateClick(popupWindow, year, month + 1, day);
                    }
                }
            });
            return popupWindow;
        }

        /**
         * 创建弹出框Dialog
         *
         * @param onDialogDateClickListener
         * @return
         */
        public Dialog createDialog(final OnDialogDateClickListener onDialogDateClickListener) {
            ArnoCalendarView kunCalendarView = create();
            final AlertDialog alertDialog = new AlertDialog.Builder(context).setView(kunCalendarView).create();
            kunCalendarView.setOnDateClickListener(new OnDateClickListener() {
                @Override
                public void onDateClick(int year, int month, int day) {
                    if (onDialogDateClickListener != null) {
                        onDialogDateClickListener.onDialogDateClick(alertDialog, year, month, day);
                    }
                }
            });
            return alertDialog;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/nuonuonuonuonuo/article/details/81511203