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();
    }

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

时间: 2021-11-14

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自定义日历控件实例详解

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

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实现可滑动的自定义日历控件

最近用到的一个日历控件,记录下,效果如图 代码下载地址:点击打开链接 布局文件 <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 一个日历控件的实现代码

先看几张动态的效果图吧! 项目地址: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日历控件的实现方法

本文实例为大家分享了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日历控件PickTime代码实例

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

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

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

iOS自定义日历控件的简单实现过程

因为程序要求要插入一个日历控件,该空间的要求是从当天开始及以后的六个月内的日历,上网查资料基本上都说只要获取两个条件(当月第一天周几和本月一共有多少天)就可以实现一个简单的日历,剩下的靠自己的简单逻辑就OK了,下面开始自己从开始到完成的整个过程 1.首先做NSDate类目,扩展一些方法让日期之间转换更加方便 #import <Foundation/Foundation.h> @interface NSDate (LYWCalendar) #pragma mark - 获取日 - (NSInte

在Android开发中使用自定义组合控件的例子

一.定义一个XML布局文件 setting_item_view.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height

Android自定义表格控件满足人们对视觉的需求

Android平台已经给我们提供了很多标准的组件,如:TextView.EditView.Button.ImageView.Menu等,还有许多布局控件,常见的有:AbsoluteLayout.LinerLayout.RelativeLayout.TableLayout等.但随着人们对视觉的需求,基本组件已无法满足人们求新求异的要求,于是我们常常会自定义组件,用来实现更美观的UI界面. 实现自定义控件通常有两种途径,一种是继承View类,重写其中的重要方法,另一种是继承ViewGroup类,通过

Android通过自定义ImageView控件实现图片的缩放和拖动的实现代码

概述:通过自定义ImageView控件,在xml布局里面调用自定的组件实现图片的缩放. /** * 自定义的ImageView控制,可对图片进行多点触控缩放和拖动 * * @author qiuwanyong */ public class MyImageView extends ImageView { /** * 初始化状态常量 */ public static final int STATUS_INIT = 1; /** * 图片放大状态常量 */ public static final i

Android自定义Gallery控件实现3D图片浏览器

本篇文章主要介绍如何使用自定义的Gallery控件,实现3D效果的图片浏览器的效果. 话不多说,先看效果. 上面是一个自定义的Gallery控件,实现倒影和仿3D的效果,下面是一个图片查看器,点击上面的小图片,可以在下面查看大图片. 下面重点说一下,实现图片查看器的思路. 1.手机中图片路径的获取 首先,先不管图片如何展示,如果我们想实现图片查看器的功能,我们首先需要做的是获取到所有的图片的路径信息,只有这样,我们才能实现对图片的查看. 我们可以使用下面的代码实现 private List<St