当前位置:   article > 正文

Android日历CalendarView当结束日期小于开始日期依旧绘制处理_com.haibin.calendarview.calendarview select_mode

com.haibin.calendarview.calendarview select_mode

如果你还需要“修改选择范围背景色(开始、结束日期背景色跟中间背景颜色不一样)”、“左右滑动切换月份实时显示当前年月”……(如下图)那我可以推荐你看一下另一篇博客:https://blog.csdn.net/weixin_40420578/article/details/96485028,其实这篇博客内容就是从中抽出来的。

日期选择范围,结束日期小于开始日期时,依旧绘制(修改源码三步骤)

在github地址:https://github.com/huanghaibin-dev/CalendarView,下载好项目,运行起来,接下来按照步骤修改

(1)CalendarUtil.java的differ(Calendar calendar1, Calendar calendar2)方法修改成如下:

  1. /**
  2. * 运算 大日期减小日期
  3. * test Pass
  4. *
  5. * @param calendar1 calendar1 第二次点击的日期
  6. * @param calendar2 calendar2 第一次点击的日期
  7. * @return 大日期减小日期
  8. */
  9. static int differ(Calendar calendar1, Calendar calendar2) {
  10. if (calendar1 == null) {
  11. return Integer.MIN_VALUE;
  12. }
  13. if (calendar2 == null) {
  14. return Integer.MAX_VALUE;
  15. }
  16. java.util.Calendar date = java.util.Calendar.getInstance();
  17. date.set(calendar1.getYear(), calendar1.getMonth() - 1, calendar1.getDay());//
  18. long startTimeMills = date.getTimeInMillis();//获得起始时间戳
  19. date.set(calendar2.getYear(), calendar2.getMonth() - 1, calendar2.getDay());//
  20. long endTimeMills = date.getTimeInMillis();//获得结束时间戳
  21. if (startTimeMills < endTimeMills) {
  22. return (int) ((endTimeMills - startTimeMills) / ONE_DAY);
  23. } else {
  24. return (int) ((startTimeMills - endTimeMills) / ONE_DAY);
  25. }
  26. }

(2)RangeMonthView.java的onClick(View v)方法,修改某行代码即可,改成如下:(RangeWeekView.java同理)

  1. //大概在168行,因为前面有改过某些代码,不知道准确行数了,如下代码
  2. int compare = calendar.compareTo(mDelegate.mSelectedStartRangeCalendar);
  3. //改成如下代码:(原因:比较两次日期大小,当第二次点击日期小于第一次点击日期时,会返回负数,反之会放回1,相等时放回0)
  4. int compare = calendar.compareTo(mDelegate.mSelectedStartRangeCalendar);
  5. if (compare < 0) {
  6. compare = mDelegate.mSelectedStartRangeCalendar.compareTo(calendar);
  7. }

(3)RangeMonthView.java的isCalendarSelected(Calendar calendar),修改成如下代码:(RangeWeekView.java同理)

  1. /**
  2. * 日历是否被选中
  3. *
  4. * @param calendar calendar
  5. * @return 日历是否被选中
  6. */
  7. protected boolean isCalendarSelected(Calendar calendar) {
  8. if (mDelegate.mSelectedStartRangeCalendar == null) {
  9. return false;
  10. }
  11. if (onCalendarIntercept(calendar)) {
  12. return false;
  13. }
  14. if (mDelegate.mSelectedEndRangeCalendar == null) {
  15. return calendar.compareTo(mDelegate.mSelectedStartRangeCalendar) == 0;
  16. }
  17. /*
  18. *原先的代码如下:
  19. *(当calendar在大于等于“第一次点击日期”而且小于等于“第二次点击日期”时为true
  20. *这个逻辑对于我们“第一次点击日期”小于“第二次点击日期”就会返回false了)
  21. * return calendar.compareTo(mDelegate.mSelectedStartRangeCalendar) >= 0 &&
  22. * calendar.compareTo(mDelegate.mSelectedEndRangeCalendar) <= 0;
  23. * */
  24. return (calendar.compareTo(mDelegate.mSelectedStartRangeCalendar) >= 0 &&calendar.compareTo(mDelegate.mSelectedEndRangeCalendar) <= 0) ||
  25. (calendar.compareTo(mDelegate.mSelectedEndRangeCalendar) >= 0 && calendar.compareTo(mDelegate.mSelectedStartRangeCalendar) <= 0);
  26. }

前方bug注意:修改三步骤后,结束日期小于开始日期是绘制了,但是不知道你选中的时间范围是什么,解决这个bug,按如下代码修改即可:

1.CalendarViewDelegate.java的getSelectCalendarRange()方法,当结束日期小于开始日期时,置换startTimeMills、endTimeMills即可,改成如下:

  1. /**
  2. * 获得选中范围
  3. *
  4. * @return 选中范围
  5. */
  6. final List<Calendar> getSelectCalendarRange() {
  7. if (mSelectMode != SELECT_MODE_RANGE) {
  8. return null;
  9. }
  10. List<Calendar> calendars = new ArrayList<>();
  11. if (mSelectedStartRangeCalendar == null ||
  12. mSelectedEndRangeCalendar == null) {
  13. return calendars;
  14. }
  15. final long ONE_DAY = 1000 * 3600 * 24;
  16. java.util.Calendar date = java.util.Calendar.getInstance();
  17. date.set(mSelectedStartRangeCalendar.getYear(),
  18. mSelectedStartRangeCalendar.getMonth() - 1,
  19. mSelectedStartRangeCalendar.getDay());//
  20. long startTimeMills = date.getTimeInMillis();//获得起始时间戳
  21. date.set(mSelectedEndRangeCalendar.getYear(),
  22. mSelectedEndRangeCalendar.getMonth() - 1,
  23. mSelectedEndRangeCalendar.getDay());//
  24. long endTimeMills = date.getTimeInMillis();
  25. //新增的代码,开始日期大于结束日期,置换
  26. if (startTimeMills > endTimeMills) {
  27. Long interTimeMills;
  28. interTimeMills = startTimeMills;
  29. startTimeMills = endTimeMills;
  30. endTimeMills = interTimeMills;
  31. }
  32. for (long start = startTimeMills; start <= endTimeMills; start += ONE_DAY) {
  33. date.setTimeInMillis(start);
  34. Calendar calendar = new Calendar();
  35. calendar.setYear(date.get(java.util.Calendar.YEAR));
  36. calendar.setMonth(date.get(java.util.Calendar.MONTH) + 1);
  37. calendar.setDay(date.get(java.util.Calendar.DAY_OF_MONTH));
  38. if (mCalendarInterceptListener != null &&
  39. mCalendarInterceptListener.onCalendarIntercept(calendar)) {
  40. continue;
  41. }
  42. LunarCalendar.setupLunarCalendar(calendar);
  43. calendars.add(calendar);
  44. }
  45. addSchemesFromMap(calendars);
  46. return calendars;
  47. }

 

 

改好后,运行测试。现在问题来了,怎么加入到项目里呢?原先我们引入日历这样子:

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,

  1. calendarview、minSdkVersion、targetSdkVersion、versionCode、versionName这些值改成跟项目的一样,
  2. 把compile改成implementation,androidTestCompile改成androidTestImplementation,testCompiletestImplementation,
  3. 注意appcompat-v7、recyclerview-v7、junit版本号跟项目一致

4.clean、rebuild一下,运行即可

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/543278
推荐阅读
相关标签
  

闽ICP备14008679号