멜팅비의 개발 공부

[Android/Kotlin] 유용한 Custom Calendar Library 소개 본문

개발 공부/[Android 개발]

[Android/Kotlin] 유용한 Custom Calendar Library 소개

멜팅비 2021. 9. 9. 23:25
반응형

안드로이드 프로젝트를 진행하다 보면 종종 만나게 되는 UI 중 하나는 바로 달력이다.

달력 UI의 경우 디자인에 따라 custom이 많이 필요하게 되는데 그때 유용하게 사용되는 라이브러리를 소개하려고 한다.

나의 경우 달력을 한 주씩 보여주는 UI를 작업하게 되었고, 활용 코드와 함께 정리하려고 한다.

 

kizitonwose/CalendarView 라이브러리

https://github.com/kizitonwose/CalendarView

 

GitHub - kizitonwose/CalendarView: A highly customizable calendar library for Android, powered by RecyclerView.

A highly customizable calendar library for Android, powered by RecyclerView. - GitHub - kizitonwose/CalendarView: A highly customizable calendar library for Android, powered by RecyclerView.

github.com

 

라이브러리 추가 방법

1. project level build.gradle 추가

allprojects {
 repositories {
    google()
    jcenter()
    maven { url "https://jitpack.io" }
 }
}

 

2. app level build.gradle 추가

dependencies {
	implementation 'com.github.kizitonwose:CalendarView:<latest-version>'
}

 

CalendarView가 필요한 화면 xml에 CalendarView 추가

<com.kizitonwose.calendarview.CalendarView
                android:id="@+id/calendarView"
                android:layout_width="match_parent"
                android:layout_height="100dp"
                app:cv_scrollMode="paged"
                app:cv_orientation="horizontal"
                app:cv_inDateStyle="none"
                app:cv_outDateStyle="none"
                app:cv_maxRowCount="1"
                app:cv_hasBoundaries="false"
                app:cv_monthHeaderResource="@layout/calendar_header_layout"
                app:cv_dayViewResource="@layout/calendar_day_layout" />

 

날짜가 표시될 TextView resource

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_month"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:textColor="@color/white"
        android:textSize="12sp" />

    <TextView
        android:id="@+id/tv_day"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="4dp"
        android:layout_marginBottom="4dp"
        android:gravity="center"
        android:textColor="@color/white"
        android:textSize="12sp" />

    <TextView
        android:id="@+id/tv_date"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:textColor="@color/white"
        android:textSize="16sp" />

</LinearLayout>

// 필요에 따라 header와 footer 영역도 커스텀이 가능

 

날짜를 표시해 줄 Container를 생성 후 Binder로 연결 및 날짜 선택 시 처리

// 날짜를 표시하는 영역 Container 클래스
inner class DayViewContainer(view: View) : ViewContainer(view) {
        val monthText: TextView = view.findViewById(R.id.tv_month)
        val dateText: TextView = view.findViewById(R.id.tv_date)
        val dayText: TextView = view.findViewById(R.id.tv_day)
        lateinit var day: CalendarDay

        init {
            view.setOnClickListener {
                // 날짜 선택 시 처리 정의
            }
        }

				// 날짜에 따라 textview에 값을 bind해줌
				fun bind(day: CalendarDay) {
            this.day = day
            monthText.text = monthFormatter.print(DateTime(day.date.toString()))
            dateText.text = dateFormatter.print(DateTime(day.date.toString()))
            dayText.text = dayFormatter.print(DateTime(day.date.toString()))

            val dayWidth = binding.calendarView.daySize.width
            dateText.layoutParams = LinearLayout.LayoutParams(dayWidth, dayWidth)

            if (day.date == selectedDate) {
                dateText.setBackgroundResource(R.drawable.calendar_selected_bg)
            } else {
                dateText.setBackgroundResource(R.color.col_transparency)
            }
        }
    }


// 날짜 binder 연결
binding.calendarView.dayBinder = object : DayBinder<DayViewContainer> {
            override fun create(view: View) = DayViewContainer(view)
            override fun bind(container: DayViewContainer, day: CalendarDay) {
								container.day = day
                container.bind(day)
            }
        }

 

액티비티 또는 프래그먼트에서 CalendarView setup

// 달력의 시작 월, 종료 월을 직접 지정 가능
// 주의 시작 값 지정 가능
val currentMonth = YearMonth.now()
        val firstMonth = currentMonth.minusMonths(10)
        val lastMonth = currentMonth.plusMonths(10)      
        val daysOfWeek = arrayOf(
                DayOfWeek.SUNDAY,
                DayOfWeek.MONDAY,
                DayOfWeek.TUESDAY,
                DayOfWeek.WEDNESDAY,
                DayOfWeek.THURSDAY,
                DayOfWeek.FRIDAY,
                DayOfWeek.SATURDAY
        )

     binding.calendarView.setup(firstMonth, lastMonth, daysOfWeek.first())
     binding.calendarView.scrollToDate(LocalDate.now())

 

 

 

CalendarView 라이브러리의 경우 ScrollMode, 날짜 색상, 선택 시 배경 UI, 달력 표현 타입 (주/월) 등 다양하게 커스텀이 가능한 옵션들이 있다.

또한 달력의 header 또는 footer 영역도 추가적으로 커스텀 할 수 있다.

달력 범위 지정 기능이나 1줄~6줄로 표현이 가능한 라이브러리로 달력 UI 구현 시 용이하게 사용될 것 같은 라이브러리이다.

반응형
Comments