Android实现日历控件示例代码

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

先上图

第一步,搭建布局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); } } @Override public 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() { @Override public 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; } @Override public int getCount() { return gvList.size(); } @Override public String getItem(int position) { return gvList.get(position); } @Override public long getItemId(int position) { return position; } @Override public 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>

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

时间: 2024-09-25 20:06:51

Android实现日历控件示例代码的相关文章

Android Studio 日历控件原码移植后不能显示日历怎么回事?

问题描述 Android Studio 日历控件原码移植后不能显示日历怎么回事? Android Studio 日历控件原码移植后,下面的日历月份都不能显示,程序没有报错,不知道是怎么回事? 解决方案 android 中的日历控件Android日历控件 解决方案二: 调试不要问这种没头没尾的问题,先检查日志,看看这个控件有没有输出什么提示,然后自己研究源码,调试显示部分代码

Android 底部导航控件实例代码_Android

一.先给大家展示下最终效果 通过以上可以看到,图一是简单的使用,图二.图三中为结合ViewPager共同使用,而且都可以随ViewPager的滑动渐变色,不同点是图二为选中非选中两张图片,图三的选中非选中是一张图片只是做了颜色变化. 二. 需求 我们希望做可以做成这样的,可以在xml布局中引入控件并绑定数据,在代码中设置监听回调,并且配置使用要非常简单! 三.需求分析 根据我们多年做不明确需求项目的经验,以上需求还算明确.那么我们可以采用在LinearLayout添加子View控件,这个子Vie

Android 底部导航控件实例代码

一.先给大家展示下最终效果 通过以上可以看到,图一是简单的使用,图二.图三中为结合ViewPager共同使用,而且都可以随ViewPager的滑动渐变色,不同点是图二为选中非选中两张图片,图三的选中非选中是一张图片只是做了颜色变化. 二. 需求 我们希望做可以做成这样的,可以在xml布局中引入控件并绑定数据,在代码中设置监听回调,并且配置使用要非常简单! 三.需求分析 根据我们多年做不明确需求项目的经验,以上需求还算明确.那么我们可以采用在LinearLayout添加子View控件,这个子Vie

android开发日历控件 可滑动?

问题描述 android开发日历控件 可滑动? 谁有做过安卓 日历控件可滑动,点击又可以编程单行日历的,也可以滑动

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

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

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

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

.net mvc页面UI之Jquery博客日历控件实现代码_实用技巧

一.效果图 二.页面文件 页面上需要添加<div id="cal"></div>标记. 三.JS代码 复制代码 代码如下: // JavaScript 日历 $(document).ready(function () {     //当前时间     $now = new Date();                      //当前的时间     $nowYear = $now.getFullYear();          //当前的年     $now

android自定义倒计时控件示例_Android

自定义TextView控件TimeTextView代码: 复制代码 代码如下: import android.content.Context;import android.content.res.TypedArray;import android.graphics.Paint;import android.text.Html;import android.util.AttributeSet;import android.widget.TextView; import com.new0315.R;

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

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