andorid 日历选择器

 先看效果图:


主要代码 

package com.example.fly

import android.annotation.SuppressLint
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.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date

class JCalendarView(context: Context, attributeSet: AttributeSet) :
    FrameLayout(context, attributeSet) {
    private var lastTv: ImageView? = null
    private  var nextTv:ImageView? = null
    private var dateTv: TextView? = null
    private  var nowTv:TextView? = null
    private var calendarRv: RecyclerView? = null
    private val addYear = 0

    private var mAdapter: CalendarAdapter=CalendarAdapter()
    @SuppressLint("SimpleDateFormat")
    private val sdf = SimpleDateFormat("yyyy-MM-dd") //日期格式化

    private val mCalendar = Calendar.getInstance() //日历控件初始化

    init {
        initView(context)
    }

    private fun initView(context: Context) {
        val inflater = LayoutInflater.from(context)
        inflater.inflate(R.layout.layout_calendar, this)
        lastTv = findViewById(R.id.lastTv)
        nextTv = findViewById(R.id.nextTv)
        dateTv = findViewById(R.id.dateTv)
        calendarRv = findViewById(R.id.recyclerView)
        nowTv = findViewById(R.id.tv_now)
        calendarRv!!.layoutManager = GridLayoutManager(context, 7)
        calendarRv!!.adapter = mAdapter
        initData()
        nowTv!!.setOnClickListener { v: View? ->
            val date = Date()
            mCalendar.time = date
            val datess = sdf.format(date)
            mAdapter.setSelectDate(Integer.valueOf(datess.substring(8)))
            initData()
        }
        nextTv!!.setOnClickListener { v: View? ->
            mCalendar.add(Calendar.MONTH, +1) //月份+1
            initData()
        }
        //“上一个”点击事件
        lastTv!!.setOnClickListener { v: View? ->
            mCalendar.add(Calendar.MONTH, -1) //月份-1
            initData()
        }
    }

    @SuppressLint("SetTextI18n")
    private fun initData() {
        val datess = sdf.format(mCalendar.time)
        dateTv!!.text ="${datess.substring(0, 4)} | ${datess.substring(5, 7)} . ${datess.substring(8) }"
        val cells = ArrayList<Date>()
        val calendar = mCalendar.clone() as Calendar //克隆日历对象
        calendar[Calendar.DAY_OF_MONTH] = 1 //置于当月第一天;
        val prevDays = calendar[Calendar.DAY_OF_WEEK] - 1 //获取上个月最后一天是星期几
        calendar.add(Calendar.DAY_OF_MONTH, -prevDays) //第一天
//        //获取每月有几周
//        int actualMaximum = calendar.getActualMaximum(Calendar.WEEK_OF_MONTH);
//        int maxCount = actualMaximum * 7;  //设置每个月最大天数
        //循环存入集合中
        while (cells.size < 35) {
            cells.add(calendar.time)
            calendar.add(Calendar.DAY_OF_MONTH, 1) //日期+1
        }
        //判断当月的最后一天是否在集合里面
        val cal = mCalendar.clone() as Calendar
        cal.add(Calendar.MONTH, 0)
        cal[Calendar.DAY_OF_MONTH] = cal.getActualMaximum(Calendar.DAY_OF_MONTH)
        val preMonth = cal.time
        if (!cells.contains(preMonth)) {
            for (i in 0..6) {
                cells.add(calendar.time)
                calendar.add(Calendar.DAY_OF_MONTH, 1)
            }
        }
        mAdapter.submitList(cells)
        mAdapter.setmListener(object : CalendarAdapter.OnItemClickListener {
            override fun onItemClick(v: View?, position: Int, data: String?) {
                dateTv!!.text ="${data!!.substring(0, 4)} | ${data.substring(5, 7)} . ${data.substring(8) }"
            }

        })
    }
}

class CalendarAdapter : RecyclerView.Adapter<CalendarAdapter.ViewHolder>() {
    private var mList: List<Date> = ArrayList()
    private var mSelectPosition = -1

    // 创建一个接口来处理点击事件
    interface OnItemClickListener {
        fun onItemClick(v: View?, position: Int, data: String?)
    }

    private var mDay = 0
    private var mListener: OnItemClickListener? = null
    fun setmListener(mListener: OnItemClickListener?) {
        this.mListener = mListener
    }


    @SuppressLint("NotifyDataSetChanged")
    fun submitList(list: List<Date>) {
        mList = list
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.item_calendar, parent, false)
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        @SuppressLint("SimpleDateFormat")
        val mDate = SimpleDateFormat("yyyy-MM-dd").format(mList[position])
        //2023-11-13
        val day = mDate.substring(8).toInt()
        val month = mDate.substring(5, 7).toInt()
        val year = mDate.substring(0, 4).toInt()
        var isTheSameMonth = false //是否与当前月份相同
        if (month == getNowMonth()) {  //月份相同
            isTheSameMonth = true
        }

        //若显示的日期月份与当前月份相同,则设置字体颜色是黑色
        if (isTheSameMonth) {
            holder.itemTv.setTextColor(Color.parseColor("#333333"))
        } else {
            holder.itemTv.setTextColor(Color.parseColor("#999999"))
        }
        if (day == 1) {
            if (month == getNowMonth()) {
                holder.itemTv.setText(getNowMonth().toString() + "月")
            } else {
                val months: Int = getNowMonth() + 1
                holder.itemTv.text = if (months > 12) 1.toString() + "月" else months.toString() + "月"
            }
            holder.itemTv.setTextColor(Color.parseColor("#E71421"))
        } else {
            holder.itemTv.text = day.toString()
        }

        //设置当前日期字体为红色
        if (getNowDay() == day && getNowMonth() == month && getNowYear() == year) {
            holder.itemTv.setTextColor(Color.parseColor("#E71421"))
            holder.layout.setBackgroundResource(R.drawable.shape_ffe2e1_rounded_20dp)
        } else {
            holder.layout.setBackgroundColor(Color.WHITE)
        }
        if (position == mSelectPosition) {
            holder.itemTv.setTextColor(Color.parseColor("#ffffff"))
            holder.layout.setBackgroundResource(R.drawable.shape_e71421_rounded_20dp)
        }
        if (day == mDay) {
            holder.itemTv.setTextColor(Color.parseColor("#ffffff"))
            holder.layout.setBackgroundResource(R.drawable.shape_e71421_rounded_20dp)
        }
        holder.layout.setOnClickListener { v: View? ->
//                    setSelectPostion(position);
            setSelectDate(day)
            mListener?.onItemClick(v, position, mDate)
        }
    }

    override fun getItemCount(): Int {
        return mList.size
    }

    @SuppressLint("NotifyDataSetChanged")
    fun setSelectPostion(postion: Int) {
        mSelectPosition = postion
        notifyDataSetChanged()
    }

    @SuppressLint("NotifyDataSetChanged")
    fun setSelectDate(day: Int) {
        mDay = day
        notifyDataSetChanged()
    }

    private fun getNowYear(): Int {
        val calendar = Calendar.getInstance()
        return calendar[Calendar.YEAR]
    }

    private fun getNowMonth(): Int {
        val calendar = Calendar.getInstance()
        return calendar[Calendar.MONTH] + 1
    }

    private fun getNowDay(): Int {
        val calendar = Calendar.getInstance()
        return calendar[Calendar.DAY_OF_MONTH]
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var itemTv: TextView
        var layout: LinearLayout

        init {
            itemTv = itemView.findViewById(R.id.itemTv)
            layout = itemView.findViewById(R.id.llayout)
        }
    }
}

布局文件

1、layout_calendar:

<?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="16dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <TextView
            android:id="@+id/dateTv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="2022年11月"
            android:layout_gravity="center"
            android:textColor="#333"
            android:textSize="14sp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/tv_now"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:text="回到今天"
            android:textColor="#999"
            android:layout_gravity="center"
            android:layout_marginStart="24dp"
            android:textSize="14sp"
            android:textStyle="bold" />
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:textColor="#999"
            android:layout_gravity="center"
            android:layout_marginStart="24dp"
            android:textSize="14sp"
            android:textStyle="bold" />

        <ImageView
            android:id="@+id/lastTv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/icon_gengduo"
            android:paddingStart="16dp"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            android:rotation="180"
            android:layout_marginEnd="8dp"
            />
        <ImageView
            android:id="@+id/nextTv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/icon_gengduo"
            android:paddingEnd="16dp"
            android:paddingTop="8dp"
            android:paddingBottom="8dp"
            />

    </LinearLayout>



    <LinearLayout
        android:id="@+id/weekLl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        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="#999"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/Tv2"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="一"
            android:textColor="#999"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/Tv3"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="二"
            android:textColor="#999"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/Tv4"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="三"
            android:textColor="#999"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/Tv5"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="四"
            android:textColor="#999"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/Tv6"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="五"
            android:textColor="#999"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/Tv7"
            android:layout_width="0dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="六"
            android:textColor="#999"
            android:textSize="14sp" />
    </LinearLayout>


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center" />

</LinearLayout>

2、item_calendar

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

    <TextView
        android:id="@+id/itemTv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="1"
        android:textColor="#999"
        android:textSize="14sp" />

</LinearLayout>

3、shape:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
 <solid android:color="#e71421"/>
    <corners android:radius="20dp"/>
</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
  <corners android:radius="20dp" />
  <solid android:color="#ffe2e1" />
</shape>

欢迎大家指正不足的地方;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/143678.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法通关村第九关-青铜挑战二分查找算法

大家好我是苏麟 , 今天聊聊二分查找算法 ...... 普通查找 普通查找就是最简单的循环查找 , 无论是有席的还是无席的都可以&#xff0c;也不需要排序&#xff0c;只需要一个个对比即可&#xff0c;但其实效率很低 : public int search(int[] arr, int target) {for (int i 0;…

GEE遥感云大数据林业应用典型案例实践及GPT模型应用

近年来遥感技术得到了突飞猛进的发展&#xff0c;航天、航空、临近空间等多遥感平台不断增加&#xff0c;数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量猛增&#xff0c;遥感数据已经越来越具有大数据特征。遥感大数据的出现为相关研究提供了前所未有的机遇&#xf…

SPSS时间序列分析:谱分析

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件请点击此链接下…

eVTOL分布式电推进(DEP)动力测试系统

产品简介 分布式电推进&#xff08;DEP&#xff09;技术因其灵活多变的机械电气化设计&#xff0c;可以大大提升动力系统的安全性冗余&#xff0c;极大增强飞行过程中的可操控性&#xff0c;同时可以有效降低本机噪音&#xff0c;最大限度提升动力系统的能源使用效率等优势&am…

释放潜能,加速创新 | 低代码赋能企业数据资产管理(附案例)

在当今数字化快速发展的时代&#xff0c;企业要想保持竞争力&#xff0c;就必须紧跟潮流&#xff0c;不断进行自我革新。其中&#xff0c;数字化转型已成为企业发展的重要一环&#xff0c;在这个过程中&#xff0c;数据资产作为企业核心竞争力的关键组成部分&#xff0c;其管理…

​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型

内容来源&#xff1a;xiaohuggg Distil-Whisper&#xff1a;比Whisper快6倍&#xff0c;体积小50%的语音识别模型 ​该模型是由Hugging Face团队开发&#xff0c;它在Whisper核心功能的基础上进行了优化和简化&#xff0c;体积缩小了50%。速度提高了6倍。并且在分布外评估集上…

条码管理在WMS仓储管理系统中的应用

在当今快节奏的商业环境中&#xff0c;仓储管理对于企业的运营和成本控制具有重要意义。为了提高管理效率和准确性&#xff0c;越来越多的企业开始采用条码管理WMS系统。本文将介绍这一系统的应用场景、条码引入WMS仓储管理系统的步骤以及其在仓储管理中的应用价值&#xff0c;…

如何使用功率放大器

功率放大器是一种用于放大电流或电压的重要设备&#xff0c;广泛应用于音频、通信、无线电和电力等领域。正确地使用功率放大器可以确保其正常工作并获得满意的性能。下面西安安泰将介绍使用功率放大器的一般步骤和注意事项。 首先&#xff0c;了解功率放大器的规格和特性非常重…

uniapp运行到安卓模拟器一直在“同步手机端程序文件完成“界面解决办法

如果你是用的模拟器是android studio创建的模拟器&#xff0c;那么你需要新创建一个android11 x86架构的模拟器&#xff1a; 创建完成后&#xff0c;启动模拟器&#xff1a; 然后在hbuilder中重新运行到这个模拟器就可以了&#xff1a; 运行结果&#xff1a; 如果你是用安…

如何在 macOS 中删除 Time Machine 本地快照

看到这个可用82GB&#xff08;458.3MB可清除&#xff09; 顿时感觉清爽&#xff0c;之前的还是可用82GB&#xff08;65GB可清除&#xff09;&#xff0c;安装个xcode都安装不上&#xff0c;费解半天&#xff0c;怎么都解决不了这个问题&#xff0c;就是买磁盘情理软件也解决不了…

leetcode:LCR 133. 位 1 的个数(python3解法)

难度&#xff1a;简单 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 1 的个数&#xff08;也被称为 汉明重量).&#xff09;。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff…

STM32 I2C详解

STM32 I2C详解 I2C简介 I2C&#xff08;Inter IC Bus&#xff09;是由Philips公司开发的一种通用数据总线 两根通信线&#xff1a; SCL&#xff08;Serial Clock&#xff09;串行时钟线&#xff0c;使用同步的时序&#xff0c;降低对硬件的依赖&#xff0c;同时同步的时序稳定…

网网络安全基础之php开发 文件读取、写入功能的实现

前言 续之前的系列&#xff0c;这里php开发的文件操作的内容读取以及文本写入的部分 文件读取代码的实现 css代码 本系列的php博客都是这个css&#xff0c;名字都是index.css /* css样式初始化 */ * {font-family: Poppins, sans-serif;margin: 0;padding: 0;box-sizing: …

新版软考高项试题分析精选(二)

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 1、除了测试程序之外&#xff0c;黑盒测试还适用于测试&#xff08; &#xff09;阶段的软件文档。 A.编码 B.总体设计 D.数据库设计 C.软件需求分析 答案&a…

基于vue 2.0的H5页面中使用高德地图定位,搜索周边商户,覆盖物标记

基于vue的H5页面中使用高德地图定位&#xff0c;搜索周边商户&#xff0c;覆盖物标记 首先安装高德地图插件 npm i amap/amap-jsapi-loader --save地图承载容器 <template><div id"container"></div> </template>地图容器样式 <style…

C语言精选练习题:(7)计算最大值和最小值的差

每日一言 欲把西湖比西子&#xff0c;淡妆浓抹总相宜。 --饮湖上初晴后雨二首其二 题目 输入10个整数&#xff0c;找出其中的最大和最小值&#xff0c;计算两者的差&#xff0c;并打印出来 解题思路 创建一个数组用循环将10个整数存到数组中用打擂台的方式求出最大和最小值打…

ModuleNotFoundError_ No module named ‘Crypto‘

当要使用 python 进行加密数据的时候报错了 from Crypto.Util.Padding import pad, unpad from Crypto.Cipher import AES报错 File "F:\huisu.py", line 1, in <module>from Crypto.Util.Padding import pad, unpad ModuleNotFoundError: No module named Cr…

2024河南光伏展|郑州光伏储能展2024|4月8-10日华中地区首展

2024第四届中国(郑州)太阳能光伏及储能产业展览会   时间&#xff1a;2024年4月8-10日   地点&#xff1a;郑州.中原国际博览中心 在全球清洁能源领域&#xff0c;一年一度的中国&#xff08;郑州&#xff09;太阳能光伏及储能产业展览会已成为业界的标杆盛会。2024年的第…

C++ 二叉树进阶

二叉搜索树 二叉搜索树概念 二叉搜索树又称二叉排序树/二叉查找树&#xff0c;它可以是空树/具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值它的…

代驾预约小程序系统源码 :提起预约,避免排队 带完整搭建教程

大家好啊&#xff0c;又到罗峰来给大家分享好用的源码系统的时间了。今天要给大家分享的第一款代驾预约小程序源码系统。传统的代驾服务中&#xff0c;用户往往需要在酒后代驾、长途驾驶等场景下&#xff0c;面对排队等待代驾司机空闲时间的繁琐过程。这不仅浪费了用户的时间和…