Android自定义实现日历控件

本文实例为大家分享了Android自定义实现日历控件的具体代码,供大家参考,具体内容如下

1. Calendar类

2. 布局

创建calendar_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:padding="20sp"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <RelativeLayout
        android:id="@+id/titleRl"
        android:layout_width="match_parent"
        android:layout_height="30dp">
        <TextView
            android:id="@+id/lastTv"
            android:text="上一月"
            android:layout_alignParentLeft="true"
            android:gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="30dp"></TextView>
        <TextView
            android:id="@+id/monthTv"
            android:text="十一月"
            android:gravity="center"
            android:layout_centerHorizontal="true"
            android:layout_width="wrap_content"
            android:layout_height="30dp"></TextView>
        <TextView
            android:id="@+id/nextTv"
            android:text="下一月"
            android:gravity="center"
            android:layout_alignParentRight="true"
            android:layout_width="wrap_content"
            android:layout_height="30dp"></TextView>
    </RelativeLayout>
    <LinearLayout
        android:id="@+id/weekLl"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/Tv7"
            android:text="日"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="30dp"></TextView>
        <TextView
            android:id="@+id/Tv1"
            android:text="一"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="30dp"></TextView>
        <TextView
            android:id="@+id/Tv2"
            android:text="二"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="30dp"></TextView>
        <TextView
            android:id="@+id/Tv3"
            android:text="三"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="30dp"></TextView>
        <TextView
            android:id="@+id/Tv4"
            android:text="四"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="30dp"></TextView>
        <TextView
            android:id="@+id/Tv5"
            android:text="五"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="30dp"></TextView>
        <TextView
            android:id="@+id/Tv6"
            android:text="六"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="30dp"></TextView>
    </LinearLayout>
    <GridView
        android:id="@+id/calendarCv"
        android:numColumns="7"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></GridView>
</LinearLayout>

创建item_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/itemTv"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></TextView>
</LinearLayout>

在activity_main.xml中

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <com.aye.newcalendar.NewCalendar
        android:id="@+id/calendarNc"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></com.aye.newcalendar.NewCalendar>
</androidx.constraintlayout.widget.ConstraintLayout>

3. 业务处理

创建NewCalendar类,继承LinearLayout

public class NewCalendar extends LinearLayout {
    private TextView lastTv,nextTv,dateTv;
    private GridView calendarGv;

    private Calendar calendar=Calendar.getInstance();  //日历控件初始化
    //重写三个构造方法
    public NewCalendar(Context context) {
        super(context);
    }
    public NewCalendar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initControl(context);  //绑定控件
    }
    public NewCalendar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initControl(context);  //绑定控件
    }
    private void initControl(Context context){
        bindControl(context);  //绑定控件
        bindControlEvent();   //绑定控件事件
    }

    //绑定控件事件方法
    private void bindControlEvent() {
        renderCalendar();
        //“下一月”点击事件
        nextTv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                calendar.add(Calendar.MONTH,+1);   //月份+1
                renderCalendar();
            }
        });
        //“上一个”点击事件
        lastTv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                calendar.add(Calendar.MONTH,-1);   //月份-1
                renderCalendar();
            }
        });
    }

    private void renderCalendar() {
        SimpleDateFormat sdf = new SimpleDateFormat("MMM yyy");  //日期格式化
        dateTv.setText(sdf.format(calendar.getTime()));  //设置月份
        ArrayList<Date> cells = new ArrayList<>();
        Calendar calendar1 = (Calendar) calendar.clone();  //克隆日历对象
        calendar1.set(Calendar.DAY_OF_MONTH, 1);  //置于当月第一天;
        int prevDays = calendar1.get(Calendar.DAY_OF_WEEK) - 1;  //获取上个月最后一天是星期几
        calendar1.add(Calendar.DAY_OF_MONTH, -prevDays);  //第一天

        int maxCount = 6 * 7;  //设置每个月最大天数
        //循环存入集合中
        while (cells.size() < maxCount) {
            cells.add(calendar1.getTime());
            calendar1.add(Calendar.DAY_OF_MONTH, 1);  //日期+1
        }
        //设置适配器
        calendarGv.setAdapter(new CalendarAdapter(getContext(),cells));
    }

    //适配器
    private class CalendarAdapter extends ArrayAdapter<Date>{
        LayoutInflater layoutInflater;
        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);
                convertView.setTag(viewHolder);
            }
            viewHolder= (ViewHolder) convertView.getTag();
            int day=date.getDate();
            viewHolder.itemTv.setText(String.valueOf(day));  //赋值

        return convertView;
        }
        class ViewHolder{
            TextView itemTv;
        }
    }
    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);
    }
}

3. 定制UI

在适配器getView()方法中,个性化日历界面

Date now=new Date();
Boolean isTheSameMonth=false;  //是否与当前月份相同
//判断显示的日期月份与当前月份相同
 if (date.getMonth()==now.getMonth()) {  //月份相同
                isTheSameMonth = true;
            }
            //若显示的日期月份与当前月份相同,则设置字体颜色是黑色
            if (isTheSameMonth) {
                viewHolder.itemTv.setTextColor(Color.parseColor("#000000"));
            }
            //设置当前日期字体为红色
            if (now.getDate()==date.getDate()&&now.getMonth()==date.getMonth()&&now.getYear()==date.getYear()){
                viewHolder.itemTv.setTextColor(Color.parseColor("#ff0000"));
            }

4. 事件监听

在NewCalendar中,首先编写长按事件的接口,然后设置适配器点击事件

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

        //适配器长按事件
        calendarGv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                if (listener==null){
                    return false;
                }else {
                    //获取长按的位置,传入onItemClick方法中
                    listener.onItemClick((Date) parent.getItemAtPosition(position));
                    return true;
                }
            }
        });

在MainActivity中,实现长按事件接口并重写方法,实现长按某个日期弹出Toast显示当前长按日期。

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        NewCalendar calendar=findViewById(R.id.calendarNc);
        calendar.listener=this;
    }
    //MainActivity实现长按事件接口
    @Override
    public void onItemClick(Date date) {
        DateFormat df= SimpleDateFormat.getDateInstance();
        Toast.makeText(this,df.format(date),Toast.LENGTH_SHORT).show();
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android日历控件的实现方法

    本文实例为大家分享了Android日历控件的实现代码,供大家参考,具体内容如下 1.效果图: 2.弹窗Dialog:SelectDateDialog: public class SelectDateDialog { private static final String TAG = "SelectDateDialog"; private Dialog dialog; private TextView dateText; private int selectYear, selectMon

  • Android使用GridLayout绘制自定义日历控件

    效果图 思路:就是先设置Gridlayout的行列数,然后往里面放置一定数目的自定义日历按钮控件,最后实现日历逻辑就可以了. 步骤: 第一步:自定义日历控件(初步) 第二步:实现自定义单个日期按钮控件 第三步:将第二步得到的控件动态添加到第一步的布局中,并实现日期逻辑 第四步:编写单个日期点击监听器接口 第一步:自定义日历控件(初步) <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmln

  • Android实现可滑动的自定义日历控件

    最近用到的一个日历控件,记录下,效果如图 代码下载地址:点击打开链接 布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical&q

  • Android日历控件PickTime代码实例

    最近做项目,需要设置用户的生日,所以做这样一个功能. 开始发觉自带的DatePicker 很是不好用. 上代码: <DatePicker android:id="@+id/dpPicker" android:datePickerMode="spinner" android:calendarViewShown="false" android:layout_marginTop="150dp" android:spinners

  • Android自定义日历控件实例详解

    为什么要自定义控件 有时,原生控件不能满足我们对于外观和功能的需求,这时候可以自定义控件来定制外观或功能:有时,原生控件可以通过复杂的编码实现想要的功能,这时候可以自定义控件来提高代码的可复用性. 如何自定义控件 下面我通过我在github上开源的Android-CalendarView项目为例,来介绍一下自定义控件的方法.该项目中自定义的控件类名是CalendarView.这个自定义控件覆盖了一些自定义控件时常需要重写的一些方法. 构造函数 为了支持本控件既能使用xml布局文件声明,也可在ja

  • Android 一个日历控件的实现代码

    先看几张动态的效果图吧! 项目地址:https://github.com/Othershe/CalendarView 这里主要记录一下在编写日历控件过程中一些主要的点: 一.主要功能 1.支持农历.节气.常用节假日 2.日期范围设置,默认支持的最大日期范围[1900.1~2049.12] 3.默认选中日期设置 4.单选.多选 5.跳转到指定日期 6.通过自定义属性定制日期外观,以及简单的日期item布局配置 二.基本结构 我们要实现的日历控件采用ViewPager作为主框架,CalendarVi

  • Android可签到日历控件的实现方法

    最近在公司的功能需求中,需要实现可以签到的日历,签到后在签到过的日期做标志.本功能参考了网上一些大神的日历控件,在此基础上进行修改,已满足本公司的需求,现已完成,记录一下. 布局文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_wi

  • Android实现日历控件示例代码

    做的是一个酒店的项目,可以选择入住和离开的日期.声明为了省事在网上找的资料,自己修改的逻辑,希望对需要的朋友有帮助.喜欢的给个好评.谢谢啦!祝生活愉快! 先上图 第一步,搭建布局xml <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_w

  • Android学习教程之日历控件使用(7)

    本文实例为大家分享了Android日历控件的使用方法,供大家参考,具体内容如下 MainActivity.java代码: package siso.timessquare; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; p

  • Android自定义实现日历控件

    本文实例为大家分享了Android自定义实现日历控件的具体代码,供大家参考,具体内容如下 1. Calendar类 2. 布局 创建calendar_layout.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="20sp" android:orientation="vertical" android:l

  • Android自定义播放器控件VideoView

    介绍 最近要使用播放器做一个简单的视频播放功能,开始学习VideoView,在横竖屏切换的时候碰到了点麻烦,不过在查阅资料后总算是解决了.在写VideoView播放视频时候定义控制的代码全写在Actvity里了,写完一看我靠代码好乱,于是就写了个自定义的播放器控件,支持指定大小,可以横竖屏切换,手动左右滑动快进快退.好了,下面开始. 效果图有点卡,我也不知道为啥..... VideoView介绍 这个是我们实现视频播放最主要的控件,详细的介绍大家百度就去看,这里介绍几个常用的方法. 用于播放视频

  • Android自定义加载控件实现数据加载动画

    本文实例为大家分享了Android自定义加载控件,第一次小人跑动的加载效果眼前一亮,相比传统的PrograssBar高大上不止一点,于是走起,自定义了控件LoadingView去实现动态效果,可直接在xml中使用,具体实现如下 package com.*****.*****.widget; import android.content.Context; import android.graphics.drawable.AnimationDrawable; import android.util.

  • Android自定义圆环倒计时控件

    本文实例为大家分享了Android自定义圆环倒计时控件的具体代码,供大家参考,具体内容如下 先来一张最终效果图: 主要思路: 在画渐变色圆环的时候,设置一个属性动画,根据属性动画的执行时长,来作为倒计时的时长.监听属性动画的进度,来达到 倒计时的目的. 二话不说,直接贴代码.具体实现思路都在注释上. 自定义属性: <declare-styleable name="CountDownProgressBar"> <attr name="countDown_cir

  • Android自定义双向滑动控件

    本文实例为大家分享了Android自定义双向滑动控件的具体代码,供大家参考,具体内容如下 先看一下效果图 1.SeekBarPressure工具类 public class SeekBarPressure extends View {     private static final String TAG = "SeekBarPressure";     private static final int CLICK_ON_LOW = 1;      //点击在前滑块上     priv

  • Android自定义折线图控件的完整步骤

    目录 前言 概述 原点 计算Y轴宽度 计算X轴高度 X轴 绘制轴线 X轴刻度间隔 网格线.文本 Y轴 计算Y轴分布 刻度间隔.网格线.文本 折线 代码 总结 前言 日前,有一个“折现图”的需求,如下图所示: 概述 如何自定义折线图?首先将折线图的绘制部分拆分成三部分: 原点 X轴 Y轴 折线 原点 第一步,需要定义出“折线图”原点的位置,由图得: 可以发现,原点的位置由X轴.Y轴所占空间决定: OriginX:Y轴宽度OriginY:View高度 - X轴高度 计算Y轴宽度 思路:遍历Y轴的绘制

  • Android自定义星星评分控件

    下面为控件的实现历程: 此控件高效,直接使用ondraw绘制,先亮照: 由于Android自身的星星评分控件样式可以改,但是他的大小不好调整的缺点,只能用small normal这样的style调整,自定义不强,因此击发了我自定义星星控件的欲望. 星星评分控件的设计,大体规划为: 需要两张图片,一颗亮星星,一颗空星星:(当然图片不一定是星星,其他图片也可以,现在实验就用星星就好了)星星数量,间距可以自定义,星星的最小步进为0.1,在用户使用的时候与Android自带的方法一样. 星星控件大体分为

  • Android自定义圆角ImageView控件

    目前一些比较火的图片加载库虽然支持圆角加载,若你是接的别人作了一半的项目,刚好别人用的图片加载库刚好不支持圆角加载,那么这颗控件你值得拥有.(支持网络图片的加载) 1.创建CustomImageView 类在你的项目中(源码如下) import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Bitmap.

  • Android自定义弹窗提醒控件使用详解

    Android中原生的Dialog弹窗提醒控件样式单一,有时候并不能满足我们的项目需求,而且一个工程里面有时候会在多处都用到弹窗提醒的功能,代码会出现大量的冗余,工作之余,就自己实现了这么一个弹窗提醒控件.自定义控件继承自我们的Dialog,样式自定义,弹窗中的文字可通过数组参数初始化,Item个数实现了动态添加,和数组长度一致.对话框底端可展示一个Item(如:确定)或两个Item(如:确定   取消),通过参数设置.废话不多说,直接上代码: 1.自定义对话框的背景样式,在res/values

随机推荐