当前位置:   article > 正文

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

com.haibin.calendarview.calendarview

一、文章背景

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

我这里主要记录上一年和下一年的使用,其他功能大家可以参考第三方库的使用Github

二、日历控件的使用

2.1、实现MonthView

  1. package com.wyy.usecalendarview
  2. import android.content.Context
  3. import android.graphics.Canvas
  4. import android.graphics.Paint
  5. import android.graphics.RectF
  6. import androidx.core.content.ContextCompat
  7. import com.haibin.calendarview.Calendar
  8. import com.haibin.calendarview.MonthView
  9. class ScheduleMonthView(context: Context) : MonthView(context) {
  10. /**
  11. * 背景圆点
  12. */
  13. private val mPointPaint = Paint()
  14. /**
  15. * 今天的背景色
  16. */
  17. private val mCurrentDayPaint = Paint()
  18. /**
  19. * 圆点半径
  20. */
  21. private var mPointRadius = 3f
  22. init {
  23. mCurrentDayPaint.isAntiAlias = true
  24. mCurrentDayPaint.style = Paint.Style.FILL
  25. mCurrentDayPaint.color = ContextCompat.getColor(context, R.color.purple_700)
  26. mPointPaint.isAntiAlias = true
  27. mPointPaint.style = Paint.Style.FILL
  28. mPointPaint.textAlign = Paint.Align.CENTER
  29. mPointPaint.color = ContextCompat.getColor(context, R.color.purple_200)
  30. }
  31. /**
  32. * 绘制选中的日子(这个绘制会覆盖标记点的显示)
  33. *
  34. * @param canvas canvas
  35. * @param calendar 日历日历calendar
  36. * @param x 日历Card x起点坐标
  37. * @param y 日历Card y起点坐标
  38. * @param hasScheme hasScheme 非标记的日期
  39. * @return 返回true 则绘制onDrawScheme,因为这里背景色不是是互斥的,所以返回true
  40. */
  41. override fun onDrawSelected(canvas: Canvas, calendar: Calendar, x: Int, y: Int, hasScheme: Boolean): Boolean {
  42. if (!calendar.isCurrentDay) {
  43. mSelectedPaint.style = Paint.Style.STROKE
  44. mSelectedPaint.strokeWidth = 2f
  45. val rectF = RectF(x.toFloat(), y.toFloat(), (x + mItemWidth).toFloat(), (y + mItemHeight).toFloat())
  46. canvas.drawRoundRect(rectF, 16f, 16f, mSelectedPaint)
  47. }
  48. return true
  49. }
  50. /**
  51. * 绘制标记的事件日子(只绘制非当天的标记点,避免重复绘制)
  52. *
  53. * @param canvas canvas
  54. * @param calendar 日历calendar
  55. * @param x 日历Card x起点坐标
  56. * @param y 日历Card y起点坐标
  57. */
  58. override fun onDrawScheme(canvas: Canvas, calendar: Calendar, x: Int, y: Int) {
  59. if (!calendar.isCurrentDay) {
  60. canvas.drawCircle((x + mItemWidth / 2).toFloat(), (y + mItemHeight - 13).toFloat(), mPointRadius, mPointPaint)
  61. }
  62. }
  63. /**
  64. * 绘制文本(如果今天有标记点,这里还需要绘制当天的标记点)
  65. *
  66. * @param canvas canvas
  67. * @param calendar 日历calendar
  68. * @param x 日历Card x起点坐标
  69. * @param y 日历Card y起点坐标
  70. * @param hasScheme 是否是标记的日期
  71. * @param isSelected 是否选中
  72. */
  73. override fun onDrawText(canvas: Canvas?, calendar: Calendar?, x: Int, y: Int, hasScheme: Boolean, isSelected: Boolean) {
  74. val cx = x + mItemWidth / 2
  75. calendar?.let {
  76. canvas?.let { cit ->
  77. if (it.isCurrentDay) {
  78. val rectF = RectF(x.toFloat(), y.toFloat(), (x + mItemWidth).toFloat(), (y + mItemHeight).toFloat())
  79. cit.drawRoundRect(rectF, 16f, 16f, mCurrentDayPaint)
  80. if (hasScheme) {
  81. // 绘制当天的标记点
  82. cit.drawCircle(
  83. (x + mItemWidth / 2).toFloat(),
  84. (y + mItemHeight - 13).toFloat(),
  85. mPointRadius,
  86. mPointPaint
  87. )
  88. }
  89. }
  90. val drawPaint = if (isSelected && !it.isCurrentDay) {
  91. mSelectTextPaint
  92. } else if (hasScheme) {
  93. if (it.isCurrentMonth) mSchemeTextPaint else mOtherMonthTextPaint
  94. } else {
  95. if (it.isCurrentDay) mCurDayTextPaint else if (it.isCurrentMonth) mCurMonthTextPaint else mOtherMonthTextPaint
  96. }
  97. cit.drawText(it.day.toString(), cx.toFloat(), mTextBaseLine + y, drawPaint)
  98. }
  99. }
  100. }
  101. }

2.2、布局代码使用示例:

  1. <com.haibin.calendarview.CalendarView
  2. android:id="@+id/cv_calendar"
  3. android:layout_width="0dp"
  4. android:layout_height="wrap_content"
  5. app:calendar_height="40dp"
  6. app:current_day_text_color="@color/black"
  7. app:current_month_text_color="@color/black"
  8. app:day_text_size="14sp"
  9. app:layout_constraintLeft_toLeftOf="parent"
  10. app:layout_constraintTop_toBottomOf="@+id/toolbar"
  11. app:layout_constraintRight_toRightOf="parent"
  12. app:month_view="com.wyy.usecalendarview.ScheduleMonthView"
  13. app:other_month_text_color="@color/teal_700"
  14. app:selected_text_color="@color/black"
  15. app:selected_theme_color="@color/purple_700"
  16. app:week_background="@android:color/transparent"
  17. app:week_bar_height="40dp"
  18. app:week_text_color="@color/black"
  19. app:week_text_size="14sp"
  20. app:month_view_show_mode="mode_all"
  21. app:select_mode="single_mode" />

2.3、注册日历的事件监听

2.3.1、监听月份切换

mDataBinding.cvCalendar.setOnMonthChangeListener(this)

2.3.2、监听选择事件

mDataBinding.cvCalendar.setOnCalendarSelectListener(this)

2.4、实现日历的监听事件

2.4.1、月份切换的实现

  1. override fun onMonthChange(year: Int, month: Int) {
  2. supportActionBar?.title = getString(R.string.title, year, month)
  3. }

2.4.2、选择事件的实现

  1. /**
  2. * 没用到
  3. */
  4. override fun onCalendarOutOfRange(calendar: Calendar?) {}
  5. /**
  6. * 用户选择的监听
  7. */
  8. override fun onCalendarSelect(calendar: Calendar?, isClick: Boolean) {
  9. Log.d(
  10. "wyy",
  11. "Selector year is ${calendar?.year},month is ${calendar?.month},day is ${calendar?.day} and isClick is $isClick"
  12. )
  13. }

2.5、操作日历控件

2.5.1、上一年

  1. mDataBinding.cvCalendar.monthViewPager.apply {
  2. currentItem -= 12
  3. }

2.5.2、下一年

  1. mDataBinding.cvCalendar.monthViewPager.apply {
  2. currentItem += 12
  3. }

2.6、demo

Github

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

闽ICP备14008679号