사이드 프로젝트를 진행하면서 캘린더를 사용하기 위해 라이브러리를 찾는 와중에 “sheet” 오픈소스 라이브러리를 확인을 통해 Contributor된 회고록을 작성해보려고 합니다.
이슈는 Github 페이지의 issue 탭에 들어가서 게시물을 작성하면 됩니다.
좌우 스와이프를 했을 때,
년, 월 Spinner Adapter의 item이 선택된 데이터와 일치하지 않는 문제를 발견하고 수정을 진행 하였습니다.
캘린더의 스와이프 이벤트를 먼저 찾아보겠습니다.
// CalendarSheet.kt
package com.maxkeppeler.sheets.calendar
...
private fun setupMonthScrollListener() {
// 캘린더의 스와이프 이벤트가 발생 되는 곳
binding.calendarView.monthScrollListener = { month ->
val day = month.weekDays.first().first { it.owner == DayOwner.THIS_MONTH }
selectedViewDate = day.date
monthAdapter.updateCurrentYearMonth(day.date.yearMonth)
updateSpinnerValues()
}
}
...
해당 함수의 동작을 파악한 결과
monthScrollListener
에서 날짜 정보를 받아서 Spinner의 value를 바꿔주고 있습니다.
선택된 Month Item 구현 코드
// MonthAdapter.kt
package com.maxkeppeler.sheets.calendar
...
// 현재 상태를 확인하여 글자의 Style를 변경하는 코드
private fun SheetsCalendarMonthItemBinding.handleState(monthAtIndex: Month) = when {
disablePast && currentSelectedYear.year == currentYearMonth.year
&& monthAtIndex.value < currentYearMonth.month.value -> {
month.isSelected = false
month.setTextAppearance(ctx, R.style.TextAppearance_MaterialComponents_Subtitle2)
month.setTextColor(textColor)
month.alpha = 0.2f
}
disableFuture && currentSelectedYear.year == currentYearMonth.year
&& monthAtIndex.value > currentYearMonth.month.value -> {
month.isSelected = false
month.setTextAppearance(ctx, R.style.TextAppearance_MaterialComponents_Subtitle2)
month.setTextColor(textColor)
month.alpha = 0.2f
}
currentYearMonth.month == monthAtIndex && selectedMonth == monthAtIndex -> {
month.isSelected = true
month.setTextAppearance(ctx, R.style.TextAppearance_MaterialComponents_Subtitle2)
month.setTextColor(primaryColor)
month.alpha = 1f
}
currentYearMonth.month == monthAtIndex -> {
month.isSelected = true
month.setTextAppearance(ctx, R.style.TextAppearance_MaterialComponents_Body2)
month.setTextColor(primaryColor)
month.alpha = 1f
}
selectedMonth == monthAtIndex -> {
month.isSelected = false
month.setTextAppearance(ctx, R.style.TextAppearance_MaterialComponents_Subtitle2)
month.setTextColor(primaryColor)
month.alpha = 1f
}
else -> {
month.isSelected = false
month.setTextAppearance(ctx, R.style.TextAppearance_MaterialComponents_Body2)
month.setTextColor(textColor)
month.alpha = 1f
}
}
// 선택된 item 변경
private fun updateSelectedMonth(month: Month) {
selectedMonth = month
notifyDataSetChanged()
}
...
해당 Adapter를 확인해보시면 private fun updateSelectedMonth(month: Month)
인데 private함수로 MonthAdapter.kt 파일 안에서만 사용할 수 있도록 구현되어 있습니다.
여기서 item의 선택된 변수가 Adapter의 click event에만 적용되어 있어 클릭을 하지 않으면 현재날짜와 item의 날짜가 다르게 표현되었습니다.
Adapter의 updateSelectedMonth(month: Month)
함수를 CalendarView.monthScrollListener(month: CalendarMonth)
에 구현해 주면 간단하게 Selected item을 구현할 수 있습니다.
구현 코드는 아래와 같습니다.
// CalendarSheet.kt
package com.maxkeppeler.sheets.calendar
...
private fun setupMonthScrollListener() {
binding.calendarView.monthScrollListener = { month ->
val day = month.weekDays.first().first { it.owner == DayOwner.THIS_MONTH }
selectedViewDate = day.date
monthAdapter.updateCurrentYearMonth(day.date.yearMonth)
// monthAdapter, yearAdapter의 updateSelected 함수 추가
monthAdapter.updateSelectedMonth(day.date.yearMonth.month)
yearAdapter.updateSelectedYear(Year.of(day.date.yearMonth.year))
updateSpinnerValues()
}
}
...
Adapter 외 다른 클래스에서 사용하기 위해서는 updateSelected()
를 공개적으로 사용할 수 있게 public으로 변경해 준다.
// MonthAdapter.kt
package com.maxkeppeler.sheets.calendar
...
// private --> public
fun updateSelectedMonth(month: Month) {
selectedMonth = month
notifyDataSetChanged()
}
...
Pull Request를 확인 후 main으로 merge가 되었다.
WoW !!
간단하지만 처음으로 오픈소스를 수정하여 Contributor이 되었다.
정말 신기하고 해당 수정버전이 merge되고 실제 프로덕션으로 배포가 되어 다른 사용자들이
사용한다고 생각하니까 뿌듯하다!!