Android 日历打卡标记:使用自定义 DayViewDecorator 显示星型图标

在 Android 应用中,使用日历组件展示用户的打卡记录是一个常见的需求。为了更直观地显示打卡日期,我们可以为这些日期添加醒目的标记,比如星型图标。本文将介绍如何使用自定义 DayViewDecorator 来实现这一功能。

1. 创建星型装饰类

首先,我们需要创建一个名为 StarDecorator 的类,并实现 DayViewDecorator 接口。该类用于定义如何装饰日历中的特定日期。

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.text.style.LineBackgroundSpan;
import android.view.View;

import com.prolificinteractive.materialcalendarview.CalendarDay;
import com.prolificinteractive.materialcalendarview.DayViewDecorator;
import com.prolificinteractive.materialcalendarview.DayViewFacade;

public class StarDecorator implements DayViewDecorator {

    private final Context context;

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

    @Override
    public boolean shouldDecorate(CalendarDay day) {
        // 根据打卡记录判断是否需要标记该日期
        // 这里假设已打卡的日期为2022年1月1日和2022年1月15日
        int year = day.getYear();
        int month = day.getMonth();
        int dayOfMonth = day.getDay();
        return (year == 2022 && month == 0 && dayOfMonth == 1) || (year == 2022 && month == 0 && dayOfMonth == 15);
    }

    @Override
    public void decorate(DayViewFacade view) {
        view.addSpan(new StarSpan());
    }

    private class StarSpan implements LineBackgroundSpan {

        private final Paint paint;

        public StarSpan() {
            paint = new Paint();
            paint.setColor(Color.YELLOW);
            paint.setStyle(Paint.Style.FILL);
            paint.setAntiAlias(true);
        }

        @Override
        public void drawBackground(
                Canvas canvas, Paint paint,
                int left, int right, int top, int baseline, int bottom,
                CharSequence charSequence,
                int start, int end, int lineNumber
        ) {
            int width = right - left;
            int height = bottom - top;

            float centerX = left + width / 2f;
            float centerY = top + height / 2f;

            float radius = Math.min(width, height) / 2f;

            Path path = createStarPath(centerX, centerY, radius);

            canvas.drawPath(path, paint);
        }

        private Path createStarPath(float centerX, float centerY, float radius) {
            Path path = new Path();
            float angle = (float) (Math.PI / 5);
            float rotation = (float) (Math.PI / 2);

            for (int i = 0; i < 5; i++) {
                float x = (float) (centerX + Math.cos(rotation + angle * i) * radius);
                float y = (float) (centerY + Math.sin(rotation + angle * i) * radius);

                if (i == 0) {
                    path.moveTo(x, y);
                } else {
                    path.lineTo(x, y);
                }
            }

            path.close();
            return path;
        }
    }
}

代码解释:

  • StarDecorator 类实现了 DayViewDecorator 接口,该接口定义了两个方法:
    • shouldDecorate(CalendarDay day):判断该日期是否需要装饰,根据打卡记录判断即可。
    • decorate(DayViewFacade view):对需要装饰的日期进行处理,例如添加星型标记。
  • StarSpan 类实现了 LineBackgroundSpan 接口,用于绘制星型图形。
  • createStarPath 方法用于创建星型形状的 Path 对象。

2. 在 MainActivity 中应用装饰器

MainActivityonClick() 方法中,添加以下代码来应用 StarDecorator

checkInButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        String currentDate = getCurrentDate();
        String currentTime = getCurrentTime();

        CheckIn checkIn = new CheckIn(currentDate, currentTime);
        appDatabase.checkInDao().insert(checkIn);

        Toast.makeText(MainActivity.this, "打卡成功:" + currentDate + " " + currentTime, Toast.LENGTH_SHORT).show();

        // 在日历上显示标记
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = sdf.parse(currentDate);
            long timeInMillis = date.getTime();
            calendarView.setDate(timeInMillis);
            calendarView.setActivated(true);

            // 应用星型标记
            StarDecorator starDecorator = new StarDecorator(MainActivity.this);
            calendarView.addDecorator(starDecorator);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
});

代码解释:

  • onClick() 方法中,获取当前日期并记录打卡信息。
  • 使用 SimpleDateFormat 将日期字符串转换为 Date 对象,并获取时间戳 timeInMillis
  • 将日历设置为当前日期,并设置 setActivated(true) 来突出显示该日期。
  • 创建 StarDecorator 对象并将其添加到日历中。

3. 运行效果

现在,当你点击打卡按钮后,选中的日期将会在日历上显示一个星型标记,以表示你已经打卡。

总结

通过自定义 DayViewDecorator,我们可以轻松地为 Android 日历组件添加各种自定义标记,例如星型、圆形等,使界面更加丰富,提升用户体验。

Android 日历打卡标记:使用自定义 DayViewDecorator 显示星型图标

原文地址: https://www.cveoy.top/t/topic/bv6Q 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录