캘린더를 사용하는 방법에 대해 배워보았습니다.
Material CalendarView Github라이브러리를 이용하여 캘린더 뷰를 공부하였습니다.
implementation 'com.prolificinteractive:material-calendarview:1.4.3'
저는 2.0.1보다 낮은 버전을 사용하였으며 더 높은 버전을 원하신다면 github에 들어가셔서 살펴 보시면 좋을 것 같습니다.
<com.prolificinteractive.materialcalendarview.MaterialCalendarView
android:id="@+id/calendarview"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:mcv_selectionColor="@color/whiteblue"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
app:mcv_selectionColor="@color/whiteblue"로 날짜 선택 시 보이는 색을 설정할 수 있으며
더욱 다양한 데코레이션 방법이 존재합니다.
타일 크기로 보기의 너비와 높이를 정의합니다.
단일 또는 다중 날짜 선택 또는 선택을 완전히 비활성화
다른 달 또는 범위를 벗어난 날짜 표시
요일 설정
날짜 범위만 표시
상단 바 사용자 정의
헤더, 평일 또는 개별 요일에 대한 사용자 정의 레이블
등이 존재합니다.
아무 데코 없이 그냥 xml에 넣을 시 위와 같은 사진이며 저는 다양한 데코를 원하기 때문에 코드로 이동해서 데코를 해보겠습니다.
//오늘을 색다르게 데코
inner class ToDayDecorator(context: Context) : DayViewDecorator {
private var date = CalendarDay.today()
val drawble = context?.resources?.getDrawable(com.example.mytodolist.R.drawable.date_select_deco, null)
override fun shouldDecorate(day: CalendarDay?): Boolean {
return day?.equals(date)!!
}
override fun decorate(view: DayViewFacade?) {
if (drawble != null) {
view?.setBackgroundDrawable(drawble)
}
}
}
오늘(현재 날짜)를 색다르게 표시하기 위한 데코레이터 클래스 입니다.
오늘 날짜를 받아오고 drawable을 통해 데코해줍니다.
inner class SundayDecorator() : DayViewDecorator {
private val calendar = Calendar.getInstance()
override fun shouldDecorate(day: CalendarDay?): Boolean {
//주어진 캘린더 인스턴스에 오늘의 정보를 복사
day?.copyTo(calendar)
//일주일을 받아옴
val weekDay = calendar.get(Calendar.DAY_OF_WEEK)
//그중 일요일을 리턴
return weekDay == Calendar.SUNDAY
}
override fun decorate(view: DayViewFacade?) {
//하루(일요일)의 전체 텍스트에 범위의 색 추가
view?.addSpan(object :ForegroundColorSpan(Color.RED){})
}
}
inner class SaturdayDecorator() : DayViewDecorator {
private val calendar = Calendar.getInstance()
override fun shouldDecorate(day: CalendarDay?): Boolean {
//주어진 캘린더 인스턴스에 오늘의 정보를 복사
day?.copyTo(calendar)
//토요일을 받아옴
val weekDay = calendar.get(Calendar.DAY_OF_WEEK)
//그중 토요일을 리턴
return weekDay == Calendar.SATURDAY
}
override fun decorate(view: DayViewFacade?) {
view?.addSpan(object :ForegroundColorSpan(Color.BLUE){})
}
}
일요일과 토요일의 데코입니다. addSpan을 통해 데코를 하였습니다. addSpan은 공식 github에 사용법이 더 자세히 나와있습니다.
inner class EventDecorator(dates: Collection<CalendarDay?>?,
context: Activity,
color : Int
/*textView: TextView?*/) : DayViewDecorator {
private var dates : HashSet<CalendarDay>
//private var textView : TextView
//private var drawable : Drawable
private var color = 0
init {
//drawable = context.resources.getDrawable(com.example.mytodolist.R.drawable.test, null)
this.dates = dates?.let { HashSet(it) }!!
this.color = color
}
override fun shouldDecorate(day: CalendarDay?): Boolean {
return dates.contains(day)
}
override fun decorate(view: DayViewFacade?) {
//view!!.setSelectionDrawable(drawable)
view!!.addSpan(DotSpan(5F, color))
}
}
이벤트를 체크하기 위해 날짜에 점을 찍는 것을 표현하였는데 이것 역시 공식github에 잘 나와있으며 drawable은 점이 있는 날짜에 drawable을 추가하는 건데 저는 넣고 싶지 않아서 주석처리 하였습니다.
위 코드들을
//시작 달의 인스턴스(현재달)
var startMonthCalendar = Calendar.getInstance()
//마지막 달의 인스턴스
var endMonthCalendar = Calendar.getInstance()
//현재 년도
val currentYear = startMonthCalendar.get(Calendar.YEAR)
//현재 월
val currentMonth = startMonthCalendar.get(Calendar.MONTH)
//현재 날짜
val currentDate = startMonthCalendar.get(Calendar.DATE)
...
//onCreateView
val sundayDeco = SundayDecorator()
val saturdayDeco = SaturdayDecorator()
val toDayDeco = context?.let { ToDayDecorator(it) }
//val monthDeco = MonthDecorator(startDate, endDate)
//val CurrentMonthDeco = CurrentMonthDecorator(startDate, endDate)
calendarList.add(CalendarDay.today())
calendarList.add(CalendarDay.from(2022, 10, 25))
val eventDeco = EventDecorator(calendarList, mainActivity, Color.BLUE)
calendarBinding.calendarview.addDecorators(sundayDeco, saturdayDeco, /*monthDeco,*/ toDayDeco/*, CurrentMonthDeco*/ , eventDeco)
addDecorators에 추가해준다면 아래 사진과 같이 데코레이터가 잘 적용되는 것을 확인 할 수 있었습니다.