做的是一个酒店的项目,可以选择入住和离开的日期。声明为了省事在网上找的资料,自己修改的逻辑,希望对需要的朋友有帮助。喜欢的给个好评。谢谢啦!祝生活愉快!
先上图

第一步,搭建布局xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayout
        android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><FrameLayout
            android:layout_width="match_parent"android:layout_height="wrap_content"><TextView
                android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/days_detail"android:gravity="center"android:padding="16dp"android:text="选择住店离店日期"android:textColor="@color/white"android:textSize="18sp" /><ImageView
                android:id="@+id/back_to_up"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginTop="10dp"android:src="@drawable/backto" /></FrameLayout><FrameLayout
            android:layout_width="match_parent"android:layout_height="wrap_content"><View
                android:layout_width="match_parent"android:layout_height="30dp"android:background="@color/days_detail" /><android.support.v7.widget.CardView
                android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="10dp"android:layout_marginTop="20dp"android:padding="10dp"app:cardCornerRadius="10dp"app:cardElevation="16dp"><LinearLayout
                    android:id="@+id/ll"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical" /></android.support.v7.widget.CardView></FrameLayout></LinearLayout>
</ScrollView>

第二部在编写逻辑

 LinearLayout ll;MyCalendar c1;Date date;String nowday;long nd = 1000 * 24L * 60L * 60L;//一天的毫秒数SimpleDateFormat simpleDateFormat, sd1, sd2;SharedPreferences sp;SharedPreferences.Editor editor;private String inday, outday//日期sp_inday, sp_outday;//周几Activity   extends BaseActivity implements MyCalendar.OnDaySelectListener {

继承BaseActivity实现点击日历的监听回调

 private void init() {List<String> listDate = getDateList();LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);for (int i = 0; i < listDate.size(); i++) {c1 = new MyCalendar(this);c1.setLayoutParams(params);Date date = null;try {date = simpleDateFormat.parse(listDate.get(i));} catch (ParseException e) {e.printStackTrace();}if (!"".equals(sp_inday)) {c1.setInDay(sp_inday);}if (!"".equals(sp_outday)) {c1.setOutDay(sp_outday);}c1.setTheDay(date);c1.setOnDaySelectListener(this);ll.addView(c1);}}@Overridepublic void onDaySelectListener(View view, String date) {//若日历日期小于当前日期,或日历日期-当前日期超过三个月,则不能点击try {if (simpleDateFormat.parse(date).getTime() < simpleDateFormat.parse(nowday).getTime()) {return;}long dayxc = (simpleDateFormat.parse(date).getTime() - simpleDateFormat.parse(nowday).getTime()) / nd;if (dayxc > 90) {return;}} catch (ParseException e) {e.printStackTrace();}//若以前已经选择了日期,则在进入日历后会显示以选择的日期,该部分作用则是重新点击日历时,清空以前选择的数据(包括背景图案)if (!"".equals(sp_inday)) {c1.viewIn.setBackgroundColor(Color.WHITE);((TextView) c1.viewIn.findViewById(R.id.tv_calendar_day)).setTextColor(Color.BLACK);((TextView) c1.viewIn.findViewById(R.id.tv_calendar)).setText("");}if (!"".equals(sp_outday)) {c1.viewOut.setBackgroundColor(Color.WHITE);((TextView) c1.viewOut.findViewById(R.id.tv_calendar_day)).setTextColor(Color.BLACK);((TextView) c1.viewOut.findViewById(R.id.tv_calendar)).setText("");}String dateDay = date.split("-")[2];if (Integer.parseInt(dateDay) < 10) {dateDay = date.split("-")[2].replace("0", "");}TextView textDayView = (TextView) view.findViewById(R.id.tv_calendar_day);TextView textView = (TextView) view.findViewById(R.id.tv_calendar);view.setBackgroundColor(Color.parseColor("#33B5E5"));textDayView.setTextColor(Color.WHITE);if (null == inday || inday.equals("")) {textDayView.setText(dateDay);textView.setText("入住");inday = date;} else {if (inday.equals(date)) {view.setBackgroundColor(Color.WHITE);textDayView.setText(dateDay);textDayView.setTextColor(Color.BLACK);textView.setText("");inday = "";} else {try {if (simpleDateFormat.parse(date).getTime() < simpleDateFormat.parse(inday).getTime()) {view.setBackgroundColor(Color.WHITE);textDayView.setTextColor(Color.BLACK);Toast.makeText(CalendarActivity.this, "离开日期不能小于入住日期", Toast.LENGTH_SHORT).show();return;}} catch (ParseException e) {e.printStackTrace();}textDayView.setText(dateDay);textView.setText("离开");outday = date;editor.putString("dateIn", inday);editor.putString("dateOut", outday);editor.commit();finish();}}}//根据当前日期,向后数三个月(若当前day不是1号,为满足至少90天,则需要向后数4个月)@SuppressLint("SimpleDateFormat")public List<String> getDateList() {List<String> list = new ArrayList<String>();Date date = new Date();int nowMon = date.getMonth() + 1;String yyyy = sd1.format(date);String dd = sd2.format(date);if (nowMon == 9) {list.add(simpleDateFormat.format(date));list.add(yyyy + "-10-" + dd);list.add(yyyy + "-11-" + dd);if (!dd.equals("01")) {list.add(yyyy + "-12-" + dd);}} else if (nowMon == 10) {list.add(yyyy + "-10-" + dd);list.add(yyyy + "-11-" + dd);list.add(yyyy + "-12-" + dd);if (!dd.equals("01")) {list.add((Integer.parseInt(yyyy) + 1) + "-01-" + dd);}} else if (nowMon == 11) {list.add(yyyy + "-11-" + dd);list.add(yyyy + "-12-" + dd);list.add((Integer.parseInt(yyyy) + 1) + "-01-" + dd);if (!dd.equals("01")) {list.add((Integer.parseInt(yyyy) + 1) + "-02-" + dd);}} else if (nowMon == 12) {list.add(yyyy + "-12-" + dd);list.add((Integer.parseInt(yyyy) + 1) + "-01-" + dd);list.add((Integer.parseInt(yyyy) + 1) + "-02-" + dd);if (!dd.equals("01")) {list.add((Integer.parseInt(yyyy) + 1) + "-03-" + dd);}} else {list.add(yyyy + "-" + getMon(nowMon) + "-" + dd);list.add(yyyy + "-" + getMon((nowMon + 1)) + "-" + dd);list.add(yyyy + "-" + getMon((nowMon + 2)) + "-" + dd);if (!dd.equals("01")) {list.add(yyyy + "-" + getMon((nowMon + 3)) + "-" + dd);}}return list;}public String getMon(int mon) {String month = "";if (mon < 10) {month = "0" + mon;} else {month = "" + mon;}return month;}

第三部 编写监听,自定义的控件

public class MyCalendar extends LinearLayout {private static Context context;private Date theInDay;private String inday = "", outday = "";public static View viewIn;public static View viewOut;public static String positionIn;public static String positionOut;public static final int WEEKDAYS = 7;public static String[] WEEK = {"周日","周一","周二","周三","周四","周五","周六"};static long nd = 1000 * 24L * 60L * 60L;//一天的毫秒数private List<String> gvList;//存放天private OnDaySelectListener callBack;//回调函数private static String nowday = new SimpleDateFormat("yyyy-MM-dd").format(new Date());private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMM");//日期格式化private static SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd");//日期格式化/*** 构造函数** @param context*/public MyCalendar(Context context) {super(context);MyCalendar.context = context;}/*** 日期变量转成对应的星期字符串** @param date* @return*/public static String DateToWeek(Date date) {Calendar calendar = Calendar.getInstance();calendar.setTime(date);int dayIndex = calendar.get(Calendar.DAY_OF_WEEK);if (dayIndex < 1 || dayIndex > WEEKDAYS) {return null;}return WEEK[dayIndex - 1];}/*** 获得天数差** @param begin* @param end* @return*/public static long getDayDiff(Date begin, Date end) {long day = 1;if (end.getTime() < begin.getTime()) {day = -1;} else if (end.getTime() == begin.getTime()) {day = 1;} else {day += (end.getTime() - begin.getTime()) / (24 * 60 * 60 * 1000);}return day;}/*** 将yyyy-MM-dd类型转换成MM.dd** @param time* @return* @throws ParseException*/public static String format1(String time) throws ParseException {SimpleDateFormat from = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);SimpleDateFormat to = new SimpleDateFormat("MM.dd", Locale.CHINA);return to.format(from.parse(time));}/*** 获得指定日期的后一天** @param specifiedDay* @return*/public static String getSpecifiedDayAfter(String specifiedDay) {Calendar c = Calendar.getInstance();Date date = null;try {date = new SimpleDateFormat("yy-MM-dd").parse(specifiedDay);} catch (ParseException e) {e.printStackTrace();}c.setTime(date);int day = c.get(Calendar.DATE);c.set(Calendar.DATE, day + 1);String dayAfter = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime());return dayAfter;}/*** 构造函数** @param context*/public MyCalendar(Context context, AttributeSet attrs) {super(context, attrs);MyCalendar.context = context;}public void setInDay(String inday) {this.inday = inday;}public void setOutDay(String outday) {this.outday = outday;}public void setTheDay(Date dateIn) {this.theInDay = dateIn;init();}/*** 初始化日期以及view等控件*/private void init() {gvList = new ArrayList<String>();//存放天final Calendar cal = Calendar.getInstance();//获取日历实例cal.setTime(theInDay);//cal设置为当天的cal.set(Calendar.DATE, 1);//cal设置当前day为当前月第一天int tempSum = countNeedHowMuchEmpety(cal);//获取当前月第一天为星期几int dayNumInMonth = getDayNumInMonth(cal);//获取当前月有多少天setGvListData(tempSum, dayNumInMonth, cal.get(Calendar.YEAR) + "-" + getMonth((cal.get(Calendar.MONTH) + 1)));View view = LayoutInflater.from(context).inflate(R.layout.comm_calendar, this, true);//获取布局,开始初始化TextView tv_year = (TextView) view.findViewById(R.id.tv_year);if (cal.get(Calendar.YEAR) > new Date().getYear()) {tv_year.setVisibility(View.VISIBLE);tv_year.setText(cal.get(Calendar.YEAR) + "年");}TextView tv_month = (TextView) view.findViewById(R.id.tv_month);tv_month.setText(String.valueOf(theInDay.getMonth() + 1));MyGridView gv = (MyGridView) view.findViewById(R.id.gv_calendar);calendarGridViewAdapter gridViewAdapter = new calendarGridViewAdapter(gvList, inday, outday);gv.setAdapter(gridViewAdapter);gv.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> adapterView, View arg1, int position, long arg3) {String choiceDay = (String) adapterView.getAdapter().getItem(position);String[] date = choiceDay.split(",");String day = date[1];if (!" ".equals(day)) {if (Integer.parseInt(day) < 10) {day = "0" + date[1];}choiceDay = date[0] + "-" + day;if (callBack != null) {//调用回调函数回调数据callBack.onDaySelectListener(arg1, choiceDay);}}}});}/*** 为gridview中添加需要展示的数据** @param tempSum* @param dayNumInMonth*/private void setGvListData(int tempSum, int dayNumInMonth, String YM) {gvList.clear();for (int i = 0; i < tempSum; i++) {gvList.add(" , ");}for (int j = 1; j <= dayNumInMonth; j++) {gvList.add(YM + "," + String.valueOf(j));}}private String getMonth(int month) {String mon = "";if (month < 10) {mon = "0" + month;} else {mon = "" + month;}return mon;}/*** 获取当前月的总共天数** @param cal* @return cal.getActualMaximum(Calendar.DATE)*/private int getDayNumInMonth(Calendar cal) {return cal.getActualMaximum(Calendar.DATE);}/*** 获取当前月第一天在第一个礼拜的第几天,得出第一天是星期几** @param cal* @return firstDayInWeek*/private int countNeedHowMuchEmpety(Calendar cal) {int firstDayInWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;Log.e("MyCalendar", String.valueOf(firstDayInWeek));return firstDayInWeek;}/*** gridview中adapter的viewholder** @author wx*/static class GrideViewHolder {TextView tvDay, tv;}/*** gridview的adapter** @author Administrator*/static class calendarGridViewAdapter extends BaseAdapter {List<String> gvList;//存放天String inday, outday;public calendarGridViewAdapter(List<String> gvList, String inday, String outday) {super();this.gvList = gvList;this.inday = inday;this.outday = outday;}@Overridepublic int getCount() {return gvList.size();}@Overridepublic String getItem(int position) {return gvList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {GrideViewHolder holder;if (convertView == null) {holder = new GrideViewHolder();convertView = inflate(context, R.layout.common_calendar_gridview_item, null);holder.tv = (TextView) convertView.findViewById(R.id.tv_calendar);holder.tvDay = (TextView) convertView.findViewById(R.id.tv_calendar_day);convertView.setTag(holder);} else {holder = (GrideViewHolder) convertView.getTag();}String[] date = getItem(position).split(",");holder.tvDay.setText(date[1]);if ((position + 1) % 7 == 0 || (position) % 7 == 0) {holder.tvDay.setTextColor(Color.parseColor("#339900"));}if (!date[1].equals(" ")) {String day = date[1];if (Integer.parseInt(date[1]) < 10) {day = "0" + date[1];}if ((date[0] + "-" + day).equals(nowday)) {holder.tvDay.setTextColor(Color.parseColor("#FF6600"));holder.tvDay.setTextSize(15);holder.tvDay.setText("今天");}if (!"".equals(inday) && (date[0] + "-" + day).equals(inday)) {convertView.setBackgroundColor(Color.parseColor("#33B5E5"));holder.tvDay.setTextColor(Color.WHITE);holder.tvDay.setText(date[1]);holder.tv.setText("入住");viewIn = convertView;positionIn = date[1];}if (!"".equals(outday) && (date[0] + "-" + day).equals(outday)) {convertView.setBackgroundColor(Color.parseColor("#33B5E5"));holder.tvDay.setTextColor(Color.WHITE);holder.tvDay.setText(date[1]);holder.tv.setText("离开");viewOut = convertView;positionOut = date[1];}try {//若日历日期<当前日期,则不能选择if (dateFormat2.parse(date[0] + "-" + day).getTime() < dateFormat2.parse(nowday).getTime()) {holder.tvDay.setTextColor(Color.parseColor("#999999"));}//若日历日期-当前日期>90天,则不能选择long dayxc = (dateFormat2.parse(date[0] + "-" + day).getTime() - dateFormat2.parse(nowday).getTime()) / nd;if (dayxc > 90) {holder.tvDay.setTextColor(Color.parseColor("#999999"));}} catch (ParseException e) {e.printStackTrace();}}return convertView;}}/*** 自定义监听接口** @author Administrator*/public interface OnDaySelectListener {void onDaySelectListener(View view, String date);}/*** 自定义监听接口设置对象** @param o*/public void setOnDaySelectListener(OnDaySelectListener o) {callBack = o;}
}

在界面显示选择的日期

接下来就是为了显示选择的日期进行逻辑判断,包括字符串的转换以及日期格式的转换,日期的计算等。

simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");if ("".equals(home_into_date.getText().toString())&& "".equals(home_out_date.getText().toString())) {inday = simpleDateFormat.format(new Date());try {//转换时间格式String changeDate = MyCalendar.format1(inday);Date dateIn = simpleDateFormat.parse(inday);//将日期转换成周String weekIn = MyCalendar.DateToWeek(dateIn);home_into_date.setText("" + changeDate + weekIn);String nextDay = MyCalendar.format1(MyCalendar.getSpecifiedDayAfter(inday));Date dateOut = simpleDateFormat.parse(MyCalendar.getSpecifiedDayAfter(inday));String weekOut = MyCalendar.DateToWeek(dateOut);home_out_date.setText("" + nextDay + weekOut);long days = MyCalendar.getDayDiff(dateIn, dateOut);home_total_days.setText("共" + (days - 1) + "晚");} catch (ParseException e) {e.printStackTrace();}} else {//这里使用sp传的值inday = pro.getString("dateIn", "");outday = pro.getString("dateOut", "");try {String changeDate = MyCalendar.format1(inday);Date dateIn = simpleDateFormat.parse(inday);//将日期转换成周String weekIn = MyCalendar.DateToWeek(dateIn);home_into_date.setText("" + changeDate + weekIn);String outDay = MyCalendar.format1(outday);Date dateOut = simpleDateFormat.parse(outday);String weekOut = MyCalendar.DateToWeek(dateOut);home_out_date.setText("" + outDay + weekOut);long days = MyCalendar.getDayDiff(dateIn, dateOut);home_total_days.setText("共" + (days - 1) + "晚");} catch (ParseException e) {e.printStackTrace();}

其中有几个布局,给图自己写吧
comm_calendar

common_calendar_gridview_item

<LinearLayout
        android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:orientation="vertical"><LinearLayout
            android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center"android:orientation="vertical"><TextView
                android:id="@+id/tv_calendar_day"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center"android:textSize="15sp" /><TextView
                android:id="@+id/tv_calendar"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center"android:textColor="#FFFFFF"android:textSize="15sp" /></LinearLayout><View
            android:layout_width="match_parent"android:layout_height="0.5dp"android:background="#E4E4E4" /></LinearLayout>

看到这里了,给个好评吧!

Android日历控件相关推荐

  1. 日历控件的android代码,Android日历控件PickTime代码实例

    Android日历控件PickTime代码实例 发布时间:2020-10-03 16:05:51 来源:脚本之家 阅读:86 作者:手撕高达的村长 最近做项目,需要设置用户的生日,所以做这样一个功能. ...

  2. android日历编程,Android日历控件PickTime代码实例

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

  3. android日历控件之显示当前月份,Android 日历方式显示的日期选择组件(日历控件之一).doc...

    运行结果: 此Widget组件只包含五个类文件: DateWidget DateWidgetDayCell DateWidgetDayHeader DayStyle SymbolButton *红色为 ...

  4. android 横向的日历,Andorid 日历控件库,可左右滑动,显示公历,农历,节假日等功能...

    封面图: demo效果图 源码目录结构 Features 日历左右滑动. 显示阳历,农历,节假日和二十四节气 实现对某月日期的单选或者多选. 使用步骤 Gradle Dependency Add th ...

  5. Android 开源控件与常用开发框架开发工具类

    Android的加载动画AVLoadingIndicatorView 项目地址: https://github.com/81813780/AVLoadingIndicatorView 首先,在 bui ...

  6. android程序日历layout,Android使用GridLayout绘制自定义日历控件

    效果图 思路:就是先设置Gridlayout的行列数,然后往里面放置一定数目的自定义日历按钮控件,最后实现日历逻辑就可以了. 步骤: 第一步:自定义日历控件(初步) 第二步:实现自定义单个日期按钮控件 ...

  7. android gridview控件使用详解_Android开发实现自定义日历、日期选择控件

    点击上方蓝字关注 ?? 来源: wenzhihao123 https://www.jianshu.com/p/a2f102c728ce 前言 最近项目需要日历效果,考虑用第三方的反而不太适合设计需求, ...

  8. Android开发之如何实现日历控件

    我们大家都知道,在Android平台3.0中才新增了日历视图控件,可以显示网格状的日历内容,那么对于3.0以下的版本要使用日历控件只能借助第三方,目前用的最多的是CalendarView. 先简单介绍 ...

  9. 记一次Android第三方日历控件CalendarView的使用

    一.文章背景 用过两个日历控件的库,有用viewpager实现的,也有用canvas实现的.在实际使用过程中,发现使用canvas实现的calendarView切换下一月和下一年这种操作时切换更流畅. ...

  10. android组合控件的焦点,撸一个简单的TV版焦点控制的日历控件

    1.效果 最近需求要一个遥控控制的日历控件,找了半天没找到轮子,就自己撸一个,先看效果图: 效果图.gif 2.XML属性,所有属性默认为效果图 calender_textSize:星期和日期的字体大 ...

最新文章

  1. 第十五周程序阅读-范型程序设计(6)
  2. 机器学习算法学习---处理分类问题常用算法(一)
  3. ALV打印不显示打印界面的问题
  4. [译]GC专家系列1:理解Java垃圾回收
  5. 使用Androidkiller编译APK文件时出现libpng error: Not a PNG file的错误
  6. OllyDBG反汇编快速找到程序入口一点分析
  7. Python爬虫教程:requests模拟登陆github
  8. 两个按钮间设置空格(间距)
  9. iOS底层探索之类的结构(上):ISA
  10. 常用方法总结--文件操作篇
  11. MemTest和Memtest86+使用教程
  12. 解决在win2003 enterprise上搭建IIS遇到的“需要Service Pack 2 CD-Rom 上的文件“问题
  13. Linux SCSI设备容量打印代码分析
  14. 复旦大学高等代数期末考试班级前几名
  15. 学一点SQL注入基础
  16. 用计算机编程解魔方,4 分钟!OpenAI 的机器手学会单手解魔方了,完全自学无需编程...
  17. LintCode-最大数
  18. java安装 错误1704_java - 从Eclipse内部启动Tomcat Mongrel插件时发生致命错误 - 堆栈内存溢出...
  19. JQ QQ表情插件
  20. ECS 7天实践训练营学习笔记——DAY5

热门文章

  1. 关于SQL sever中创建表时出现“对象名无效”的情况
  2. 显示器尺寸 和 屏幕分辨率 和 有源信号分辨率 关系
  3. 恩淑 2004-12-18
  4. 龙须酥nbsp;[我的饮食情节#9352;]
  5. Java数据结构树实验报告总结_20172302 《Java软件结构与数据结构》实验二:树实验报告...
  6. 按照python后没有菜单栏 知乎_在线按汉字偏旁部首查字
  7. codeforces 1077E Thematic Contests
  8. springboot+美容院会员管理系统 毕业设计-附源码191740
  9. 大数据技术原理与应用之可视化实训
  10. java服务监控并发送邮件_详解Spring Boot Admin监控服务上下线邮件通知