feat(live-reservation-all): 주간 캘린더 라이브러리 제거 및 개별 구현

This commit is contained in:
2025-10-22 12:12:02 +09:00
parent ff236ee6a1
commit dd236d8f19
6 changed files with 157 additions and 117 deletions

View File

@@ -60,7 +60,7 @@ android {
APPLINK_HOST : "voiceon.onelink.me",
FACEBOOK_APP_ID : "612448298237287",
FACEBOOK_CLIENT_TOKEN: "32af760f4a7b7cb7e3b1e7ffd0b0da70",
KAKAO_APP_KEY: "231cf78acfa8252fca38b9eedf87c5cb"
KAKAO_APP_KEY : "231cf78acfa8252fca38b9eedf87c5cb"
]
}
@@ -86,7 +86,7 @@ android {
APPLINK_HOST : "voiceon-test.onelink.me",
FACEBOOK_APP_ID : "608674328645232",
FACEBOOK_CLIENT_TOKEN: "3775e6ea83236a685d264b6c5a1bbb4d",
KAKAO_APP_KEY: "20cf19413d63bfdfd30e8e6dff933d33"
KAKAO_APP_KEY : "20cf19413d63bfdfd30e8e6dff933d33"
]
}
}
@@ -177,8 +177,6 @@ dependencies {
implementation 'com.github.bumptech.glide:glide:5.0.5'
annotationProcessor 'com.github.bumptech.glide:compiler:5.0.5'
implementation "com.michalsvec:single-row-calednar:1.0.0"
// google in-app-purchase
implementation "com.android.billingclient:billing-ktx:6.2.0"

View File

@@ -0,0 +1,9 @@
package kr.co.vividnext.sodalive.live.reservation.all
data class DayItem(
val year: Int,
val month: Int, // 0-11
val day: Int,
val dayOfWeek: Int, // Calendar.DAY_OF_WEEK
val epochMillis: Long
)

View File

@@ -5,16 +5,9 @@ import android.content.Intent
import android.graphics.Rect
import android.os.Bundle
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.michalsvec.singlerowcalendar.calendar.CalendarChangesObserver
import com.michalsvec.singlerowcalendar.calendar.CalendarViewManager
import com.michalsvec.singlerowcalendar.calendar.SingleRowCalendarAdapter
import com.michalsvec.singlerowcalendar.selection.CalendarSelectionManager
import com.michalsvec.singlerowcalendar.utils.DateUtils
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.base.BaseActivity
import kr.co.vividnext.sodalive.common.Constants
@@ -46,6 +39,7 @@ class LiveReservationAllActivity : BaseActivity<ActivityLiveReservationAllBindin
private lateinit var loadingDialog: LoadingDialog
private lateinit var adapter: LiveReservationAdapter
private lateinit var calendarAdapter: WeekCalendarAdapter
private lateinit var selectedDateString: String
override fun onCreate(savedInstanceState: Bundle?) {
@@ -54,108 +48,37 @@ class LiveReservationAllActivity : BaseActivity<ActivityLiveReservationAllBindin
}
private fun setupCalendar() {
val myCalendarViewManager = object : CalendarViewManager {
override fun setCalendarViewResourceId(
position: Int,
date: Date,
isSelected: Boolean
): Int {
return if (isSelected)
R.layout.item_calendar_selected
else
R.layout.item_calendar
}
val dates = buildNext7Days()
calendarAdapter = WeekCalendarAdapter(
dates = dates,
onDateSelected = { dayItem ->
onSelectDate(dayItem)
},
selectedBgRes = R.drawable.bg_round_corner_4_7_3bb9f1
)
override fun bindDataToCalendarView(
holder: SingleRowCalendarAdapter.CalendarViewHolder,
date: Date,
position: Int,
isSelected: Boolean
) {
holder.itemView.findViewById<TextView>(
R.id.tv_date_calendar_item
).text = DateUtils.getDayNumber(date)
val tvDayCalendarItem = holder.itemView.findViewById<TextView>(
R.id.tv_day_calendar_item
)
tvDayCalendarItem.text = DateUtils.getDay3LettersName(date)
val cal = Calendar.getInstance()
cal.time = date
when (cal[Calendar.DAY_OF_WEEK]) {
Calendar.SATURDAY -> tvDayCalendarItem.setTextColor(
ContextCompat.getColor(
applicationContext,
R.color.color_2f90b7
)
)
Calendar.SUNDAY -> tvDayCalendarItem.setTextColor(
ContextCompat.getColor(
applicationContext,
R.color.color_a94400
)
)
else -> tvDayCalendarItem.setTextColor(
ContextCompat.getColor(
applicationContext,
R.color.white
)
)
}
}
binding.rvCalendar.apply {
layoutManager = LinearLayoutManager(
applicationContext,
LinearLayoutManager.HORIZONTAL,
false
)
this.adapter = calendarAdapter
setHasFixedSize(true)
}
// using calendar changes observer we can track changes in calendar
val myCalendarChangesObserver = object :
CalendarChangesObserver {
// you can override more methods, in this example we need only this one
override fun whenSelectionChanged(isSelected: Boolean, position: Int, date: Date) {
if (isSelected) {
val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
selectedDateString = sdf.format(date.time)
adapter.clear()
viewModel.page = 1
viewModel.isLast = false
viewModel.getLiveReservation(selectedDateString)
}
super.whenSelectionChanged(isSelected, position, date)
}
}
// selection manager is responsible for managing selection
val mySelectionManager = object : CalendarSelectionManager {
override fun canBeItemSelected(position: Int, date: Date): Boolean {
return true
}
}
binding.calendarView.apply {
calendarViewManager = myCalendarViewManager
calendarChangesObserver = myCalendarChangesObserver
calendarSelectionManager = mySelectionManager
setDates(getDates(mutableListOf()))
init()
select(0)
}
onSelectDate(dates.first())
}
private fun getDates(list: MutableList<Date>): List<Date> {
// load dates of whole month
val calendar = Calendar.getInstance()
val currentMonth = calendar[Calendar.MONTH]
calendar.set(Calendar.MONTH, currentMonth)
calendar.set(Calendar.DAY_OF_MONTH, calendar[Calendar.DAY_OF_MONTH])
list.add(calendar.time)
for (index in 1..6) {
calendar.add(Calendar.DATE, +1)
list.add(calendar.time)
}
calendar.add(Calendar.DATE, -1)
return list
private fun onSelectDate(dayItem: DayItem) {
val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
selectedDateString = sdf.format(Date(dayItem.epochMillis))
calendarAdapter.selectDate(dayItem)
adapter.clear()
viewModel.page = 1
viewModel.isLast = false
viewModel.getLiveReservation(selectedDateString)
}
@SuppressLint("NotifyDataSetChanged")
@@ -362,4 +285,29 @@ class LiveReservationAllActivity : BaseActivity<ActivityLiveReservationAllBindin
}
)
}
private fun buildNext7Days(): List<DayItem> {
val list = ArrayList<DayItem>(7)
val cal = Calendar.getInstance() // device timezone
// "오늘 00:00"로 정규화(선택 비교를 쉽게)
cal.set(Calendar.HOUR_OF_DAY, 0)
cal.set(Calendar.MINUTE, 0)
cal.set(Calendar.SECOND, 0)
cal.set(Calendar.MILLISECOND, 0)
repeat(7) { i ->
if (i > 0) cal.add(Calendar.DAY_OF_MONTH, 1)
list.add(
DayItem(
year = cal.get(Calendar.YEAR),
month = cal.get(Calendar.MONTH), // 0~11
day = cal.get(Calendar.DAY_OF_MONTH),
dayOfWeek = cal.get(Calendar.DAY_OF_WEEK), // 1=일, 7=토
epochMillis = cal.timeInMillis
)
)
}
return list
}
}

View File

@@ -0,0 +1,89 @@
package kr.co.vividnext.sodalive.live.reservation.all
import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import kr.co.vividnext.sodalive.R
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
class WeekCalendarAdapter(
private val dates: List<DayItem>,
private val onDateSelected: (DayItem) -> Unit,
@DrawableRes private val selectedBgRes: Int
) : RecyclerView.Adapter<WeekCalendarAdapter.DateVH>() {
private var selectedKey: Long? = null // "자정 millis"로 비교
@SuppressLint("NotifyDataSetChanged")
fun selectDate(day: DayItem) {
selectedKey = day.epochMillis
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DateVH {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_calendar, parent, false)
return DateVH(view)
}
override fun onBindViewHolder(holder: DateVH, position: Int) {
val day = dates[position]
holder.bind(
day,
day.epochMillis == selectedKey,
selectedBgRes,
onDateSelected
)
}
override fun getItemCount() = dates.size
class DateVH(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val textDay = itemView.findViewById<TextView>(R.id.tv_day_calendar_item)
private val textDate = itemView.findViewById<TextView>(R.id.tv_date_calendar_item)
private val container = itemView.findViewById<LinearLayout>(R.id.ll_calendar_item)
private val dayFormatter = SimpleDateFormat("EEE", Locale.getDefault())
fun bind(
day: DayItem,
isSelected: Boolean,
@DrawableRes selectedBgRes: Int,
onDateSelected: (DayItem) -> Unit
) {
// 1) 표시 텍스트(요일 약칭, 일자)
val cal = Calendar.getInstance().apply { timeInMillis = day.epochMillis }
textDay.text = dayFormatter.format(cal.time) // 예: Sun, Mon …
textDate.text = day.day.toString()
// 2) 요일별 글자색 (토: 파랑, 일: 빨강, 그 외: 흰색)
val ctx = itemView.context
val color = when (day.dayOfWeek) {
Calendar.SATURDAY -> ContextCompat.getColor(ctx, R.color.color_2f90b7)
Calendar.SUNDAY -> ContextCompat.getColor(ctx, R.color.color_a94400)
else -> ContextCompat.getColor(ctx, R.color.white)
}
textDay.setTextColor(color)
textDate.setTextColor(color)
// 3) 선택 배경
container.background = if (isSelected) {
AppCompatResources.getDrawable(ctx, selectedBgRes)
} else {
null // 또는 ColorDrawable(Color.TRANSPARENT)
}
// 4) 클릭 처리
itemView.setOnClickListener { onDateSelected(day) }
}
}
}

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -10,16 +9,13 @@
android:id="@+id/toolbar"
layout="@layout/detail_toolbar" />
<com.michalsvec.singlerowcalendar.calendar.SingleRowCalendar
android:id="@+id/calendar_view"
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_calendar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:clipToPadding="false"
android:paddingHorizontal="15.3dp"
app:deselection="false"
app:longPress="false"
app:multiSelection="false" />
android:paddingHorizontal="15.3dp" />
<View
android:layout_width="match_parent"
@@ -63,10 +59,10 @@
android:layout_height="wrap_content"
android:fontFamily="@font/gmarket_sans_medium"
android:gravity="center"
android:lineSpacingExtra="8dp"
android:text="지금 예약중인 라이브가 없습니다.\n다른 날짜의 라이브를 예약하고 참여해 보세요."
android:textColor="@color/color_bbbbbb"
android:textSize="13sp"
android:lineSpacingExtra="8dp"
tools:ignore="SmallSp" />
</LinearLayout>
</LinearLayout>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/cl_calendar_item"
android:id="@+id/ll_calendar_item"
android:layout_width="53.3dp"
android:layout_height="66.7dp"
android:layout_marginHorizontal="6.7dp"