欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义实现日历控件

程序员文章站 2022-06-18 13:29:40
本文实例为大家分享了android自定义实现日历控件的具体代码,供大家参考,具体内容如下1. calendar类2. 布局创建calendar_layout.xml

本文实例为大家分享了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();
    }

Android自定义实现日历控件

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