import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

public class CalendarView extends LinearLayout {
    private Context context;
    private GridView gridView;
    private TextView tvMonth;
    private CalendarAdapter adapter;
    private Calendar currentDate = Calendar.getInstance();
    private SimpleDateFormat dateFormat = new SimpleDateFormat('MMMM yyyy', Locale.getDefault());
    private Set<Date> markedDates = new HashSet<>();

    public CalendarView(Context context) {
        super(context);
        this.context = context;
        initialize();
    }

    public CalendarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initialize();
    }

    public CalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        initialize();
    }

    private void initialize() {
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.calendar_view, this);

        gridView = findViewById(R.id.gridview);
        tvMonth = findViewById(R.id.tv_month);

        findViewById(R.id.btn_prev).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                currentDate.add(Calendar.MONTH, -1);
                updateCalendar();
            }
        });

        findViewById(R.id.btn_next).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                currentDate.add(Calendar.MONTH, 1);
                updateCalendar();
            }
        });

        updateCalendar();
    }

    public void markDate(Date date) {
        markedDates.add(date);
        adapter.notifyDataSetChanged();
    }

    private void updateCalendar() {
        List<Date> dates = getDates();
        adapter = new CalendarAdapter(context, dates, currentDate, markedDates);
        gridView.setAdapter(adapter);
        tvMonth.setText(dateFormat.format(currentDate.getTime()));
    }

    private List<Date> getDates() {
        List<Date> dates = new ArrayList<>();
        Calendar calendar = (Calendar) currentDate.clone();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        int firstDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        calendar.add(Calendar.DAY_OF_MONTH, -firstDayOfWeek);

        while (dates.size() < 42) {
            dates.add(calendar.getTime());
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }

        return dates;
    }
}

使用说明:

  1. 创建一个名为 calendar_view.xml 的布局文件,用于定义日历视图的外观,包括 GridView、月份显示文本和导航按钮。
  2. 创建一个名为 CalendarAdapter 的适配器类,用于管理日期数据的显示和处理日期点击事件。
  3. 在你的 Activity 或 Fragment 中,使用 CalendarView 类来实例化日历视图,并使用 markDate() 方法标记特定的日期。

代码说明:

  • CalendarView 类继承自 LinearLayout,并包含一个 GridView 用于显示日历网格,以及两个按钮用于在月份之间导航。
  • getDates() 方法计算并返回一个包含 42 个日期对象的列表,用于填充日历网格,确保每个月都显示完整六周。
  • updateCalendar() 方法更新日历视图以显示当前月份的日期,并使用 CalendarAdapter 类将日期数据绑定到 GridView
  • markDate() 方法允许你标记特定的日期,例如高亮显示或添加特殊图标。

注意:

  • 你需要根据你的需求自定义 calendar_view.xmlCalendarAdapter 类。
  • 可以根据需要添加更多功能,例如处理日期点击事件、显示事件标记等。
Android自定义日历控件:实现灵活的日期标记和显示

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

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