自定义可滑动日历

这篇博客详细介绍了如何创建一个自定义的可滑动日历,包括设计思路和实现过程。日历由星期部分、日期部分组成,可以通过滑动切换月份。作者通过自定义View分别实现了星期和日期的绘制,其中日期部分使用了自定义view的方式,而非GridView。日历布局由LinearLayout、TextView和两个自定义View组合而成,可与ViewPager配合实现滑动效果。

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

自定义可滑动日历

先放上效果图,可左右滑动切换月份,默认会显示当前月份,并且会高亮当前日期。有一个类似iphone日历的按下效果。
在这里插入图片描述

一、设计思路

整个控件是一个LinearLayout,在其中分为三个部分:1、最上端显示月份,会随着中间日历的滑动改变,用一个TextView实现。2、接着一行显示星期,用自定义View实现。3、主体显示日期,可以通过左右滑动切换月份。通过ViewPager实现左右滑页,每一页的内容为自定义view。其中日期部分想到了两种思路,一种是将日期填充至GridView,一种是自定义view的方式,本文采用了后者。
在这里插入图片描述

二、实现

1、星期部分

这一行是静态的,我是通过一个自定义View实现的,当然也可以放7个TextView,宽度平均分一下就好了。
新建CustomWeekView.java继承自View。
在构造函数中初始化画笔Paint。在设置TextSize的时候,使用了一个固定值乘了一个density,主要是为了适配不同机型不同分辨率的。

private void initPaint() {
   
   
    float density = getContext().getApplicationContext().getResources().getDisplayMetrics().density;
    mTtPaint = new Paint();
    mTtPaint.setTextSize(12 * density);
    mTtPaint.setColor(Color.GRAY);
    mTtPaint.setAntiAlias(true);
}

重写onMeasure(),指定控件的宽和高。调用Math.round()方法将得到的heightSize进行四舍五入取整。高度要确保可以将所有的内容显示出来。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   
   
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);   //获取宽的尺寸
    float heightSize = FontUtil.getFontHeight(mTtPaint);//保证week显示区域可以容下最高的字母
    mOneWidth = widthSize / 7;
    setMeasuredDimension(widthSize, Math.round(heightSize));
}

重写OnDraw(),在for循环中每次调用Canvas.drawText()进行绘制。

private final String[] WEEK_ARRAY = new String[]{
   
   "日", "一", "二", "三", "四", "五", "六"};
@Override
protected void onDraw(Canvas canvas) {
   
   
    for(int i = 0; i < WEEK_ARRAY.length; i++){
   
   
        int len = (int)FontUtil.getFontlength(mTtPaint, WEEK_ARRAY[i]);
        int x = i * mOneWidth + (mOneWidth - len) / 2;
        canvas.drawText(WEEK_ARRAY[i], x, FontUtil.getFontLeading(mTtPaint), mTtPaint);
    }
}

这一块很容易实现,内容也不多,接下来是重点部分了。

2、日期部分

首先确定高度,因为按每行7天计算,有的月份需要5行,有的需要6行,为了统一,我们将整个高度设为每行高度 x 6,这样既能保证任何月份都可显示全,也能避免换页的时候页面高度来回改变。而每行高度设为背景圆圈直径加上间距。接着通过for循环来画这个月所有的日期,如果为当前月,当前日期会画一个背景圈圈,在选择日期时会有一个按下效果。最后在onTouchEvent()中计算这个按下效果。
新建CustomDateView.java,继承自View。
在构造函数中获取一些自定义的属性参数。mMinSlop这个参数可能现在看着有点懵,它的含义会在后面写onTouchEvent()的时候说明。

public CustomDateView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
   
   
    super(context, attrs, defStyleAttr);
    float density = context.getApplicationContext().getResources().getDisplayMetrics().density;
    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomDateView, defStyleAttr, 0);
    mNormalTextColor = a.getColor(R.styleable.CustomDateView_mTextColorDay, Color.BLACK);
    mSelectTextColor = a.getColor(R.styleable.CustomDateView_mSelectTextColor, Color.BLACK);
    mCurrentTextColor = a.getColor(R.styleable.CustomDateView_mCurrentTextColor, getResources().getColor(R.color.colorCurrentText));
    mTextSize = a.getDimension(R.styleable.CustomDateView_mTextSizeDay, density * 14);
    mCurrentBgd = a.getColor(R.styleable.CustomDateView_mCurrentBg, getResources()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值