赞
踩
如果你还需要“修改选择范围背景色(开始、结束日期背景色跟中间背景颜色不一样)”、“左右滑动切换月份实时显示当前年月”……(如下图)那我可以推荐你看一下另一篇博客:https://blog.csdn.net/weixin_40420578/article/details/96485028,其实这篇博客内容就是从中抽出来的。
日期选择范围,结束日期小于开始日期时,依旧绘制(修改源码三步骤)
在github地址:https://github.com/huanghaibin-dev/CalendarView,下载好项目,运行起来,接下来按照步骤修改
(1)CalendarUtil.java的differ(Calendar calendar1, Calendar calendar2)方法修改成如下:
- /**
- * 运算 大日期减小日期
- * test Pass
- *
- * @param calendar1 calendar1 第二次点击的日期
- * @param calendar2 calendar2 第一次点击的日期
- * @return 大日期减小日期
- */
- static int differ(Calendar calendar1, Calendar calendar2) {
- if (calendar1 == null) {
- return Integer.MIN_VALUE;
- }
- if (calendar2 == null) {
- return Integer.MAX_VALUE;
- }
- java.util.Calendar date = java.util.Calendar.getInstance();
-
- date.set(calendar1.getYear(), calendar1.getMonth() - 1, calendar1.getDay());//
-
- long startTimeMills = date.getTimeInMillis();//获得起始时间戳
-
- date.set(calendar2.getYear(), calendar2.getMonth() - 1, calendar2.getDay());//
-
- long endTimeMills = date.getTimeInMillis();//获得结束时间戳
-
- if (startTimeMills < endTimeMills) {
- return (int) ((endTimeMills - startTimeMills) / ONE_DAY);
-
- } else {
- return (int) ((startTimeMills - endTimeMills) / ONE_DAY);
-
- }
-
- }
(2)RangeMonthView.java的onClick(View v)方法,修改某行代码即可,改成如下:(RangeWeekView.java同理)
- //大概在168行,因为前面有改过某些代码,不知道准确行数了,如下代码
- int compare = calendar.compareTo(mDelegate.mSelectedStartRangeCalendar);
-
- //改成如下代码:(原因:比较两次日期大小,当第二次点击日期小于第一次点击日期时,会返回负数,反之会放回1,相等时放回0)
- int compare = calendar.compareTo(mDelegate.mSelectedStartRangeCalendar);
- if (compare < 0) {
- compare = mDelegate.mSelectedStartRangeCalendar.compareTo(calendar);
- }
(3)RangeMonthView.java的isCalendarSelected(Calendar calendar),修改成如下代码:(RangeWeekView.java同理)
-
- /**
- * 日历是否被选中
- *
- * @param calendar calendar
- * @return 日历是否被选中
- */
- protected boolean isCalendarSelected(Calendar calendar) {
- if (mDelegate.mSelectedStartRangeCalendar == null) {
- return false;
- }
- if (onCalendarIntercept(calendar)) {
- return false;
- }
- if (mDelegate.mSelectedEndRangeCalendar == null) {
- return calendar.compareTo(mDelegate.mSelectedStartRangeCalendar) == 0;
- }
-
- /*
- *原先的代码如下:
- *(当calendar在大于等于“第一次点击日期”而且小于等于“第二次点击日期”时为true
- *这个逻辑对于我们“第一次点击日期”小于“第二次点击日期”就会返回false了)
- * return calendar.compareTo(mDelegate.mSelectedStartRangeCalendar) >= 0 &&
- * calendar.compareTo(mDelegate.mSelectedEndRangeCalendar) <= 0;
- * */
- return (calendar.compareTo(mDelegate.mSelectedStartRangeCalendar) >= 0 &&calendar.compareTo(mDelegate.mSelectedEndRangeCalendar) <= 0) ||
- (calendar.compareTo(mDelegate.mSelectedEndRangeCalendar) >= 0 && calendar.compareTo(mDelegate.mSelectedStartRangeCalendar) <= 0);
- }
前方bug注意:修改三步骤后,结束日期小于开始日期是绘制了,但是不知道你选中的时间范围是什么,解决这个bug,按如下代码修改即可:
1.CalendarViewDelegate.java的getSelectCalendarRange()方法,当结束日期小于开始日期时,置换startTimeMills、endTimeMills即可,改成如下:
- /**
- * 获得选中范围
- *
- * @return 选中范围
- */
- final List<Calendar> getSelectCalendarRange() {
- if (mSelectMode != SELECT_MODE_RANGE) {
- return null;
- }
- List<Calendar> calendars = new ArrayList<>();
- if (mSelectedStartRangeCalendar == null ||
- mSelectedEndRangeCalendar == null) {
- return calendars;
- }
- final long ONE_DAY = 1000 * 3600 * 24;
- java.util.Calendar date = java.util.Calendar.getInstance();
-
- date.set(mSelectedStartRangeCalendar.getYear(),
- mSelectedStartRangeCalendar.getMonth() - 1,
- mSelectedStartRangeCalendar.getDay());//
-
- long startTimeMills = date.getTimeInMillis();//获得起始时间戳
-
-
- date.set(mSelectedEndRangeCalendar.getYear(),
- mSelectedEndRangeCalendar.getMonth() - 1,
- mSelectedEndRangeCalendar.getDay());//
- long endTimeMills = date.getTimeInMillis();
- //新增的代码,开始日期大于结束日期,置换
- if (startTimeMills > endTimeMills) {
- Long interTimeMills;
- interTimeMills = startTimeMills;
- startTimeMills = endTimeMills;
- endTimeMills = interTimeMills;
- }
- for (long start = startTimeMills; start <= endTimeMills; start += ONE_DAY) {
- date.setTimeInMillis(start);
- Calendar calendar = new Calendar();
- calendar.setYear(date.get(java.util.Calendar.YEAR));
- calendar.setMonth(date.get(java.util.Calendar.MONTH) + 1);
- calendar.setDay(date.get(java.util.Calendar.DAY_OF_MONTH));
- if (mCalendarInterceptListener != null &&
- mCalendarInterceptListener.onCalendarIntercept(calendar)) {
- continue;
- }
- LunarCalendar.setupLunarCalendar(calendar);
- calendars.add(calendar);
- }
- addSchemesFromMap(calendars);
- return calendars;
- }
改好后,运行测试。现在问题来了,怎么加入到项目里呢?原先我们引入日历这样子:
implementation 'com.haibin:calendarview:3.6.5'
改好源码后,怎么引入到项目里面呢?我的做法是把calendarview一整个libar引入到项目中,步骤如下:
1.选中calendarview右键——Show in Explorer(就是找到calendarview的路径);
2.选中项目(自己的项目)右键——New——Module——Import Gradle Project——Next——选择calendarview路径——Next;
3.修改calendarview的gradle,
- calendarview、minSdkVersion、targetSdkVersion、versionCode、versionName这些值改成跟项目的一样,
-
- 把compile改成implementation,androidTestCompile改成androidTestImplementation,testCompiletestImplementation,
-
- 注意appcompat-v7、recyclerview-v7、junit版本号跟项目一致
4.clean、rebuild一下,运行即可
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。