Android 自定义日历控件

在这里插入图片描述

package com.hzcy.doctor.view;

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

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.hzcy.doctor.R;
import com.hzcy.doctor.hospital.bean.PlanBean;

import org.w3c.dom.Text;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 新日历视图
 *
 * @author zhangpenghui
 * @date 2022/11/10
 */
public class NewCalendarView extends LinearLayout {
    private ImageView lastTv, nextTv;
    private TextView dateTv;
    private GridView calendarGv;

    private Calendar calendar = Calendar.getInstance();  //日历控件初始化

    public NewCalendarListener listener;
    CalendarAdapter calendarAdapter;

    //重写三个构造方法
    public NewCalendarView(Context context) {
        super(context);
    }

    public NewCalendarView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initControl(context);  //绑定控件
    }

    public NewCalendarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initControl(context);  //绑定控件
    }

    private void initControl(Context context) {
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        bindControl(context);  //绑定控件
        bindControlEvent();   //绑定控件事件
    }

    //绑定控件事件方法
    private void bindControlEvent() {
        renderCalendar();
        //“下一月”点击事件
        nextTv.setOnClickListener(v -> {
            calendar.add(Calendar.MONTH, +1);   //月份+1
            renderCalendar();
            if (listener != null) {
                Date date = new Date();
                int month = getMonth();
                listener.onNextMonth(month - date.getMonth());
            }
        });
        //“上一个”点击事件
        lastTv.setOnClickListener(v -> {
            calendar.add(Calendar.MONTH, -1);   //月份-1
            renderCalendar();
            if (listener != null) {
                Date date = new Date();
                int month = getMonth();
                listener.onNextMonth(month - date.getMonth());
            }
        });
    }

    private int getMonth() {
        int month = calendar.get(Calendar.MONTH);
        return month;
    }


    private void renderCalendar() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");  //日期格式化
        dateTv.setText(sdf.format(calendar.getTime()));  //设置月份
        ArrayList<Date> cells = new ArrayList<>();
        Calendar calendar1 = (Calendar) calendar.clone();  //克隆日历对象
        calendar1.setFirstDayOfWeek(Calendar.MONDAY);
        calendar1.set(Calendar.DAY_OF_MONTH, 1);  //置于当月第一天;
        int prevDays = calendar1.get(Calendar.DAY_OF_WEEK) - 2;  //获取上个月最后一天是星期几
        calendar1.add(Calendar.DAY_OF_MONTH, -prevDays);  //第一天
        //修改星期排列后 每月第一天可能不是1号  日期需要前推一周
        int day = calendar1.get(Calendar.DAY_OF_MONTH);
        int monthO = calendar1.get(Calendar.MONTH);
        int monthN = calendar.get(Calendar.MONTH);
        if (monthO == monthN && day > 1) {
            calendar1.add(Calendar.DAY_OF_MONTH, -7);
        }
//        获取每月有几周
        int actualMaximum = calendar.getActualMaximum(Calendar.WEEK_OF_MONTH);
        int maxCount = actualMaximum * 7;  //设置每个月最大天数
        //循环存入集合中
        while (cells.size() < maxCount) {
            cells.add(calendar1.getTime());
            calendar1.add(Calendar.DAY_OF_MONTH, 1);  //日期+1
        }
        calendarAdapter = new CalendarAdapter(getContext(), cells);
        //设置适配器
        calendarGv.setAdapter(calendarAdapter);
        //适配器长按事件
        calendarGv.setOnItemClickListener((parent, view, position, id) -> {
            if (listener == null) {

            } else {
                //获取长按的位置,传入onItemClick方法中
                Date atPosition = (Date) parent.getItemAtPosition(position);
                listener.onItemClick(atPosition);
                calendarAdapter.selectDate(atPosition);
            }
        });
    }

    public void setListener(NewCalendarListener listener) {
        this.listener = listener;
    }

    //适配器
    private class CalendarAdapter extends ArrayAdapter<Date> {
        LayoutInflater layoutInflater;
        Date selDate = null;

        public CalendarAdapter(@NonNull Context context, ArrayList<Date> days) {
            super(context, R.layout.item_layout, days);
            layoutInflater = LayoutInflater.from(context);
        }

        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            Date date = getItem(position);
            ViewHolder viewHolder;
            if (convertView == null) {  //初始化绑定
                convertView = layoutInflater.inflate(R.layout.item_layout, parent, false);
                viewHolder = new ViewHolder();
                viewHolder.itemTv = convertView.findViewById(R.id.itemTv);
                viewHolder.itemState = convertView.findViewById(R.id.itemState);
                viewHolder.layView = convertView.findViewById(R.id.lay);
                convertView.setTag(viewHolder);
            }
            viewHolder = (ViewHolder) convertView.getTag();
            int day = date.getDate();
            viewHolder.itemTv.setText(String.valueOf(day));  //赋值

            Date now = new Date();
            if (selDate != null) {
                now = selDate;
            }
            Boolean isTheSameMonth = false;  //是否与当前月份相同
            //判断显示的日期月份与当前月份相同
//            if (date.getMonth() == now.getMonth()) {  //月份相同
//                isTheSameMonth = true;
//            }
            if (date.getMonth() == getMonth()) {  //月份相同
                isTheSameMonth = true;
            }
            //若显示的日期月份与当前月份相同,则设置字体颜色是黑色
            if (isTheSameMonth) {
                viewHolder.itemTv.setTextColor(Color.parseColor("#333333"));
            } else {
                viewHolder.itemTv.setTextColor(Color.parseColor("#999999"));
            }
            //设置当前日期字体为红色
            if (now.getDate() == date.getDate() && now.getMonth() == date.getMonth() && now.getYear() == date.getYear()) {
//                viewHolder.itemTv.setTextColor(Color.parseColor("#ff0000"));
                viewHolder.layView.setBackground(getContext().getResources().getDrawable(R.drawable.bg_corner_4_20_p));
                viewHolder.itemState.setTextColor(Color.WHITE);
            } else {
                viewHolder.layView.setBackgroundColor(Color.WHITE);
                viewHolder.itemState.setTextColor(getContext().getResources().getColor(R.color.theme_color));
            }

            String ds = new SimpleDateFormat("yyyy-MM-dd").format(date);
//            System.out.println(ds);
//            PlanBean planBean = mapList.get(ds);
            if (mapList.containsKey(ds)) {
                viewHolder.itemState.setText("出诊");
            } else {
                viewHolder.itemState.setText("");
            }

            return convertView;
        }

        public void selectDate(Date date) {
            selDate = date;
            notifyDataSetChanged();
        }

        class ViewHolder {
            TextView itemTv;
            TextView itemState;
            View layView;
        }
    }

    //长按事件接口
    public interface NewCalendarListener {
        void onItemClick(Date date);

        void onNextMonth(int next);
    }

    //控件绑定方法
    private void bindControl(Context context) {
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.calendar_layout, this);


        lastTv = findViewById(R.id.lastTv);
        nextTv = findViewById(R.id.nextTv);
        dateTv = findViewById(R.id.dateTv);
        calendarGv = findViewById(R.id.calendarGv);
    }


    Map<String, PlanBean> mapList = new HashMap<>();

    public void showListData(List<PlanBean> ls) {
        mapList.clear();
        for (PlanBean bean : ls) {
//            System.out.println(bean.getDate());
            mapList.put(bean.getDate(), bean);
        }
        calendarAdapter.notifyDataSetChanged();
    }

    public PlanBean getPostionBean(Date date) {
        String ds = new SimpleDateFormat("yyyy-MM-dd").format(date);
        return mapList.get(ds);
    }

    //    设置选择今天高亮
    public void setSelect() {
        calendarAdapter.selectDate(new Date());
    }
}

package com.hzcy.doctor.hospital.bean

import com.hzcy.doctor.net.response.PlanShiftsListRes

class PlanBean {
    var date: String? = ""
    var week: String? = ""
    var day: Int? = 0
    var month: Int? = 0
    var year: Int? = 0
    var shiftIds: List<String>? = ArrayList()
    var shifts: List<PlanShiftsListRes>? = ArrayList()
}

calendar_layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="@dimen/d20dp">

    <androidx.appcompat.widget.LinearLayoutCompat
        android:id="@+id/titleRl"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/d20dp"
        android:gravity="center_vertical">

        <ImageView
            android:id="@+id/lastTv"
            android:layout_width="@dimen/d40dp"
            android:layout_height="@dimen/d20dp"
            android:gravity="center"
            android:src="@mipmap/ic_calendar_left" />

        <TextView
            android:id="@+id/dateTv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:text="2022年11月"
            android:textColor="@color/color_333333"
            android:textSize="@dimen/d14sp"
            android:textStyle="bold" />

        <ImageView
            android:id="@+id/nextTv"
            android:layout_width="@dimen/d40dp"
            android:layout_height="@dimen/d20dp"
            android:gravity="center"
            android:src="@mipmap/ic_calendar_right" />
    </androidx.appcompat.widget.LinearLayoutCompat>

    <LinearLayout
        android:id="@+id/weekLl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/d20dp"
        android:orientation="horizontal">


        <TextView
            android:id="@+id/Tv1"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="周一"
            android:textColor="@color/color_333333"
            android:textSize="@dimen/d12sp" />

        <TextView
            android:id="@+id/Tv2"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="周二"
            android:textColor="@color/color_333333"
            android:textSize="@dimen/d12sp" />

        <TextView
            android:id="@+id/Tv3"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="周三"
            android:textColor="@color/color_333333"
            android:textSize="@dimen/d12sp" />

        <TextView
            android:id="@+id/Tv4"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="周四"
            android:textColor="@color/color_333333"
            android:textSize="@dimen/d12sp" />

        <TextView
            android:id="@+id/Tv5"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="周五"
            android:textColor="@color/color_333333"
            android:textSize="@dimen/d12sp" />

        <TextView
            android:id="@+id/Tv6"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="周六"
            android:textColor="@color/color_333333"
            android:textSize="@dimen/d12sp" />

        <TextView
            android:id="@+id/Tv7"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="周日"
            android:textColor="@color/color_333333"
            android:textSize="@dimen/d12sp" />
    </LinearLayout>

    <GridView
        android:id="@+id/calendarGv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:numColumns="7" />

</LinearLayout>

item_layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/lay"
    android:layout_width="@dimen/d40dp"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/itemTv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/d8dp"
        android:gravity="center"
        android:text="1"
        android:textColor="@color/color_999999"
        android:textSize="@dimen/d14sp" />

    <TextView
        android:id="@+id/itemState"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/d5dp"
        android:layout_marginBottom="@dimen/d5dp"
        android:text="出诊"
        android:textColor="@color/theme_color"
        android:textSize="@dimen/d12sp" />

</LinearLayout>
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Android Studio提供了很多可用于开发日历控件的库和组件。以下是一些常用的日历控件库: 1. CalendarView:这是一个标准的Android库,它提供了一个日历视图,可以选择特定的日期。 2. MaterialCalendarView:这是一个Material Design库,提供了更具有吸引力的日历视图,并支持多种日期选择模式。 3. CompactCalendarView:这是一个轻量级的日历控件库,可以在应用程序中嵌入一个简单的、可自定义日历视图。 4. HorizontalCalendarView:这是一个水平滚动的日历控件库,可以在应用程序中添加一个可滚动的、可定制的日历视图。 以上这些库都可以通过在Android Studio中添加相关的依赖项来使用。要使用这些库,你可以在build.gradle文件中添加相关的依赖项,然后在你的代码中实例化并使用这些库提供的视图。 ### 回答2: Android Studio日历控件是一种用于在Android应用程序中显示和管理日期的工具。它提供了一个用户界面,可以让用户选择日期、查看月历和日历,并在界面中显示选定的日期。 在使用日历控件时,我们可以自定义各种属性,如选择器颜色、年份文字颜色、月份文字颜色、日期文字颜色、单元格背景色等等。我们也可以设置日历控件的默认日期、最小和最大日期、可用日期区间等等。 我们可以通过xml文件或编程方式来使用日历控件。通过代码编程的方法,我们需要创建一个CalendarView对象,并为其设置各种属性和监听器。而通过xml文件来使用日历控件,则需要在xml文件中添加CalendarView标签,并设置各种属性和监听器。 除此之外,我们还可以为日历控件设置多种监听器,如日期改变监听器、长按日期监听器、选择日期监听器等等,从而可以灵活地处理各种事件。 总之,Android Studio日历控件Android应用程序中不可或缺的工具之一,它可以为用户提供方便的日期选择和管理功能,同时也为开发人员提供灵活的定制和监听选项。 ### 回答3: Android Studio是一个主要为Android开发者提供的一个开发环境。而日历控件Android Studio中非常常见的一个控件。 在Android Studio中,日历控件可以通过使用DatePicker和CalendarView控件实现。DatePicker控件可以方便地让用户选择日期,而CalendarView控件则可以让用户在一个日历视图中查看特定日期的详细信息。 要使用DatePicker控件,需要在xml布局文件中添加DatePicker控件并设置监听事件。监听器可以获取用户选择的日期,并将其用于后续处理。例如,可以将选择的日期在应用中保存下来展示给用户,或将其发送给后端进行相关处理。 要使用CalendarView控件,也需要在xml布局文件中添加CalendarView控件并设置监听事件。通过监听器获取到用户选择的日期,我们可以进一步进行处理。例如,可以根据某一天的详细信息来显示当天的具体行程或计划,并帮助用户更好地管理他们的时间。 在Android Studio中使用日历控件可以帮助开发人员以一种易于理解的方式展示日期和时间,并且为用户提供给管理时间的有效工具。随着几乎所有应用都需要一些形式的日期和时间管理,日历控件Android Studio中的一个关键组件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魑魅魍魉9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值