Android自定义日历控件(附效果图)

本文介绍如何根据具体需求,参考网上资源并进行修改,创建一个自定义的Android日历组件。内容涵盖控件设计的细节,包括单选和多选效果的实现,并提供了实际效果图。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考了一些网上的资料,针对自己需求做了一些修改。没有难点,只是细节特别多。

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
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值