参考了一些网上的资料,针对自己需求做了一些修改。没有难点,只是细节特别多。
package xxx.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/**
* 自定义日历控件
* Created with Android Studio
* Author:
* Date:2017/12/21
*/
public class MyCalendar extends View {
private static final int SINGLE_SELECT_TYPE = 1;//单选模式
private static final int DOUBLE_SELECT_TYPE = 2;//多选模式
public static final String FORMAT_DATE_DIVIDE = "/";
private static final int RANGE_START = 1;
private static final int RANGE_END = 2;
private static final int RANGE_INSIDE = 3;
private static final int RANGE_OUTSIDE = 4;
private int mTitleTextColor;//标题的颜色
private int mSubTitleTextColor;//小标题的颜色
private float mTitleTextSize;//标题的字体大小
private float mSubTitleTextSize;//小标题的字体大小
private int mTitleArrowLeftId, mTitleArrowRightId;
private float mMonthHorizontalSpace;
private float mTitleVerticalSpac;
private float mSubTitleVerticalSpac;
private int mTextColorWeek;//星期的颜色
private float mTextSizeWeek;//星期的字体大小
private int mPastDayTxtColor;//过去的日期文本的颜色
private int mDayTextColor;//日期文本的颜色
private float mTextSizeDay;//日期文本大小
private int mSelectTextColor;//选中的文本的颜色
private int mSelectBgColor;//选中背景
private int mSelectRangeBgColor;//选中区间背景色
private float mSelectRadius;//日期圆形背景的半径
private float mLineSpac;//行间距
private Paint mPaint = new Paint();//文字画笔
private Paint mBgPaint = new Paint();//背景画笔
private Paint mArrowPaint = new Paint();//画箭头画笔
private float mTitleHeight;//顶部标题高度
private float mWeekHeight;//星期高度
private float mSubTitleHeight;//年月小标题高度
private float mDayHeight;//日期高度
private float oneHeight;//一行日期的高度,包含间距
private int mColumnWidth;//每列宽度
private Date mUpdateMonthDate; //当前的月份
private boolean isCurrentMonth;//展示的月份是否是当前月
private int mCurrentDay;//当前日
private int mUpdateYear;//当前日历所在年份
private int mUpdateMonth;//当前日历所在月份
private int mLastSelectDay;//上一次选中的日期(避免造成重复回调请求)
private int mSelectDay;//选中的日期
private int mDayOfMonth;//月份天数
private int mFirstDayIdx;//当月第一天位置索引,第一天是不同星期,起点也就不同
private int mFirstLineNum, mLastLineNum; //第一行、最后一行能展示多少日期
private int mLineNum;//日期行数
private int mArrowLeftStart;//左箭头响应触摸的起始位置
private int mArrowRightStart;//右箭头响应触摸的起始位置
private int mArrowWidth;//箭头图标宽度
private String[] mWeekArray = new String[]{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
private long mStartMills;//选中区域的起始点
private long mEndMills;//选中区域的结束点
private IClickListener mListener;
private boolean showTitle;//是否显示标题
private boolean showWeek;//是否显示星期
private boolean showSubTitle;//是否显示年月小标题
private float mPadTop, mPadBottom;
private GestureDetector mGestureDetector;
private int mType = SINGLE_SELECT_TYPE;
public MyCalendar(Context context) {
this(context, null);
}
public MyCalendar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyCalendar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context
.obtainStyledAttributes(attrs, R.styleable.MyCalendar, defStyleAttr, 0);
mTitleArrowLeftId = a.getResourceId(R.styleable.MyCalendar_arrowLeftResId, 0);
showTitle = a.getBoolean(R.styleable.MyCalendar_showTitle, true);
showWeek = a.getBoolean(R.styleable.MyCalendar_showWeek, true);
showSubTitle = a.getBoolean(R.styleable.MyCalendar_showSubTitle, false);
mTitleArrowRightId = a.getResourceId(R.styleable.MyCalendar_arrowRightResId, 0);
mMonthHorizontalSpace = a.getDimension(R.styleable.MyCalendar_titleHozSpace, 20);
mTitleVerticalSpac = a.getDimension(R.styleable.MyCalendar_titleVerticalSpace, 20);
mSubTitleVerticalSpac = a
.getDimension(R.styleable.MyCalendar_subTitleVerticalSpace, 20);
mTitleTextColor = a.getColor(R.styleable.MyCalendar_titleTextColor, Color.BLACK);
mSubTitleTextColor = a.getColor(R.styleable.MyCalendar_subTitleTextColor, Color.BLACK);
mTitleTextSize = a.getDimension(R.styleable.MyCalendar_titleTextSize, 100);
mPadTop = a.getDimension(R.styleable.MyCalendar_padTop, 10);
mPadBottom = a.getDimension(R.styleable.MyCalendar_padBottom, 10);
mSubTitleTextSize = a.getDimension(R.styleable.MyCalendar_subTitleTextSize, 100);
mTextColorWeek = a.getColor(R.styleable.MyCalendar_weekTextColor, Color.BLACK);
mTextSizeWeek = a.getDimension(R.styleable.MyCalendar_weekTextSize, 70);
mDayTextColor = a.getColor(R.styleable.MyCalendar_dayTextColor, Color.GRAY);
mPastDayTxtColor = a.getColor(R.styleable.MyCalendar_pastDayTextColor, Color.GRAY);
mTextSizeDay = a.getDimension(R.styleable.MyCalendar_dayTextSize, 70);
mSelectTextColor = a.getColor(R.styleable.MyCalendar_selectTextColor, Color.YELLOW);
mSelectBgColor = a.getColor(R.styleable.MyCalendar_selectBgColor, Color.YELLOW);
mSelectRangeBgColor = a.getColor(R.styleable.MyCalendar_selectRangeBgColor, Color.YELLOW);
mSelectRadius = a.getDimension(R.styleable.MyCalendar_selectRadius, 20);
mLineSpac = a.getDimension(R.styleable.MyCalendar_daylineSpace, 20);
a.recycle();
ini