自定义效果实现日历的选中效果

目前项目中实现的效果是默认是当天,然后效果是实心的矩形框。如果选中别的日期今天的日期变成空心矩形框,选中的日期显示是实心的矩形框。然后根据当天有没有训练数据展示实心的圆点效果。很类似OPPO手机原带的日历效果。当前是根据NCalendar自定义效果实现。

整体的效果是自定义CalendarPainter实现,代码中根据是不是今天绘制效果 以及是否被选中 画笔绘制矩形框。以及单独的绘制今天是否有任务的红点。方法中都有注释。

public class CustomPainter implements CalendarPainter {
    protected Paint mTextPaint;
    protected Paint mBgPaint;
    //圆点的半径
    private int mCircleRadius;
    private Context mContext;
    private ICalendar mICalendar;
    protected Paint mSelectenPaint;
    private List<LocalDate> mPointList;


    public CustomPainter(Context context, ICalendar iCalendar) {
        mContext = context;
        mICalendar = iCalendar;
        mTextPaint = getPaint();
        mBgPaint = getmBgPaint();
        mSelectenPaint = getmSelectenPaint();
        mPointList = new ArrayList<>();
        mCircleRadius = DensityUtil.dp2px(2);


    }

    private Paint getPaint() {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setTextAlign(Paint.Align.CENTER);
        return paint;
    }

    private Paint getmSelectenPaint() {
        mSelectenPaint = new Paint();
        mSelectenPaint.setAntiAlias(true);
        mSelectenPaint.setStyle(Paint.Style.FILL);
        mSelectenPaint.setColor(0xFFFF2271);
        return mSelectenPaint;
    }

    /**
     * 当前背景
     *
     * @return
     */
    private Paint getmBgPaint() {
        Paint mCurrentDayPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCurrentDayPaint.setAntiAlias(true);
        mCurrentDayPaint.setStrokeWidth(DensityUtil.dp2px(1));
        mCurrentDayPaint.setStyle(Paint.Style.STROKE);
        mCurrentDayPaint.setColor(0xFFFF2271);
        return mCurrentDayPaint;
    }

    @Override
    public void onDrawToday(Canvas canvas, RectF rectF, LocalDate localDate, List<LocalDate> checkedDateList) {
        //如果是今天的话 绘制矩形
        drawSelectBg(canvas, rectF, CalendarUtil.isToday(localDate), checkedDateList.contains(localDate));
        drawSolar(canvas, rectF, localDate, checkedDateList.contains(localDate), true);
        drawPoint(canvas, rectF, localDate);
    }

    @Override
    public void onDrawCurrentMonthOrWeek(Canvas canvas, RectF rectF, LocalDate localDate, List<LocalDate> checkedDateList) {
        drawSelectBg(canvas, rectF, CalendarUtil.isToday(localDate), checkedDateList.contains(localDate));
        drawSolar(canvas, rectF, localDate, checkedDateList.contains(localDate), true);
        drawPoint(canvas, rectF, localDate);
    }

    @Override
    public void onDrawLastOrNextMonth(Canvas canvas, RectF rectF, LocalDate localDate, List<LocalDate> checkedDateList) {
        drawSelectBg(canvas, rectF, CalendarUtil.isToday(localDate), checkedDateList.contains(localDate));
        drawSolar(canvas, rectF, localDate, checkedDateList.contains(localDate), true);
        drawPoint(canvas, rectF, localDate);
    }

    //绘制公历
    private void drawSolar(Canvas canvas, RectF rectF, LocalDate localDate, boolean isSelected, boolean isCurrectMonthOrWeek) {
        mTextPaint.setTextSize(DensityUtil.dp2px(16));
        //如果是今天 并且被选中
        if (CalendarUtil.isToday(localDate) && isSelected) {
            mTextPaint.setColor(Color.WHITE);
            //如果是今天没被选中
        } else if (CalendarUtil.isToday(localDate)) {
            mTextPaint.setColor(Color.RED);
        } else {
            //其他情况就是被选中的就是白色 不被选中就是黑色
            mTextPaint.setColor(isSelected ? Color.WHITE : Color.BLACK);
        }
        mTextPaint.setAlpha(isCurrectMonthOrWeek ? 255 : 100);
        canvas.drawText(localDate.getDayOfMonth() + "", rectF.centerX(), getBaseLineY(rectF), mTextPaint);
    }

    //canvas.drawText的基准线
    private int getBaseLineY(RectF rectF) {
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float top = fontMetrics.top;
        float bottom = fontMetrics.bottom;
        int baseLineY = (int) (rectF.centerY() - top / 2 - bottom / 2);
        return baseLineY;
    }

    //绘制选中背景
    private void drawSelectBg(Canvas canvas, RectF rectF, boolean isToday, boolean isisSelected) {
        float v = rectF.centerX();
        float y = rectF.centerY();
        float left = rectF.left;
        float right = rectF.right;
        float top = rectF.top;
        float bottom = rectF.bottom;
        L.e("当前的上下左右", "中x" + v + "中y" + y + "左" + left + "右" + right + "上" + top + "下" + bottom);
        //float left, float top, float right, float bottom
        rectF.set(v - DensityUtil.dp2px(15), y - DensityUtil.dp2px(15), v + DensityUtil.dp2px(15), y + DensityUtil.dp2px(15));
        if (isToday && isisSelected) {
            canvas.drawRoundRect(rectF, 8f, 8f, mSelectenPaint);
        } else if (isToday) {
            // 画圆角矩形
            canvas.drawRoundRect(rectF, 8f, 8f, mBgPaint);
        } else if (isisSelected) {
            canvas.drawRoundRect(rectF, 8f, 8f, mSelectenPaint);
        }
    }

    /**
     * dp转px
     *
     * @param context context
     * @param dpValue dp
     * @return px
     */
    public int dipToPx(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 画圆点
     */

    //设置标记
    public void setPointList(List<String> list) {
        mPointList.clear();
        for (int i = 0; i < list.size(); i++) {
            LocalDate localDate = null;
            try {
                localDate = new LocalDate(list.get(i));
            } catch (Exception e) {
                throw new RuntimeException("setPointList的参数需要 yyyy-MM-dd 格式的日期");
            }
            mPointList.add(localDate);
        }
        mICalendar.notifyCalendar();
    }

    //绘制哪一天有课程
    private void drawPoint(Canvas canvas, RectF rectF, LocalDate localDate) {
        if (mPointList.contains(localDate)) {
            canvas.drawCircle(rectF.centerX(), rectF.centerY() + DensityUtil.dp2px(20), mCircleRadius, mSelectenPaint);
        }
    }
}

翻页的时候获取每个月中有当前是否有任务数据然后设置给Calendar 重新绘制圆点setPointList()f方法

/***
 * 获取本月数据
 */
private void getPlanOfMonth(String selectMonth) {

    new MineMissionPresenter().getCalendarHistory(selectMonth, new HttpJsonCallback<JSONArray>() {
        @Override
        public void requestSuccess(JSONArray jsonArray) {

            ArrayList<TrainHistoryMonthBean> list = GsonUtil.fromListJson(jsonArray.toString(), TrainHistoryMonthBean.class);
            if (list != null && list.size() != 0) {
                for (TrainHistoryMonthBean bean : list) {
                    if (bean.getHasPlan() > 0 || bean.getHasCourse() > 0 || bean.getHasPlanMission() > 0) {
                        String ymd = bean.getYmd();
                        if (!mList.contains(ymd)) {
                            mList.add(ymd);
                        }

                    }
                }
                if (painter != null) {
                    painter.setPointList(mList);
                }

            }

        }

        @Override
        public void onError(String error) {
        }
    });
}

GitHub - yannecer/NCalendar: 一款安卓日历,仿miui,钉钉,华为的日历,万年历、365、周日历,月日历,月视图、周视图滑动切换,农历,节气,Andriod Calendar , MIUI Calendar,小米日历

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值