From dd236d8f193c2e2c3da4d02dccd25ede68ae8f4f Mon Sep 17 00:00:00 2001 From: klaus Date: Wed, 22 Oct 2025 12:12:02 +0900 Subject: [PATCH] =?UTF-8?q?feat(live-reservation-all):=20=EC=A3=BC?= =?UTF-8?q?=EA=B0=84=20=EC=BA=98=EB=A6=B0=EB=8D=94=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B0=9C=EB=B3=84=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 6 +- .../sodalive/live/reservation/all/DayItem.kt | 9 + .../all/LiveReservationAllActivity.kt | 156 ++++++------------ .../reservation/all/WeekCalendarAdapter.kt | 89 ++++++++++ .../layout/activity_live_reservation_all.xml | 12 +- app/src/main/res/layout/item_calendar.xml | 2 +- 6 files changed, 157 insertions(+), 117 deletions(-) create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/DayItem.kt create mode 100644 app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/WeekCalendarAdapter.kt diff --git a/app/build.gradle b/app/build.gradle index f723265f..acf18b59 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/DayItem.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/DayItem.kt new file mode 100644 index 00000000..cb2c146f --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/DayItem.kt @@ -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 +) diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/LiveReservationAllActivity.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/LiveReservationAllActivity.kt index 64978a11..74deb157 100644 --- a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/LiveReservationAllActivity.kt +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/LiveReservationAllActivity.kt @@ -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 + 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( - R.id.tv_date_calendar_item - ).text = DateUtils.getDayNumber(date) - - val tvDayCalendarItem = holder.itemView.findViewById( - 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): List { - // 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 { + val list = ArrayList(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 + } } diff --git a/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/WeekCalendarAdapter.kt b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/WeekCalendarAdapter.kt new file mode 100644 index 00000000..e45ee456 --- /dev/null +++ b/app/src/main/java/kr/co/vividnext/sodalive/live/reservation/all/WeekCalendarAdapter.kt @@ -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, + private val onDateSelected: (DayItem) -> Unit, + @DrawableRes private val selectedBgRes: Int +) : RecyclerView.Adapter() { + + 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(R.id.tv_day_calendar_item) + private val textDate = itemView.findViewById(R.id.tv_date_calendar_item) + private val container = itemView.findViewById(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) } + } + } +} diff --git a/app/src/main/res/layout/activity_live_reservation_all.xml b/app/src/main/res/layout/activity_live_reservation_all.xml index 163ddaf7..a8338654 100644 --- a/app/src/main/res/layout/activity_live_reservation_all.xml +++ b/app/src/main/res/layout/activity_live_reservation_all.xml @@ -1,6 +1,5 @@ - + android:paddingHorizontal="15.3dp" /> diff --git a/app/src/main/res/layout/item_calendar.xml b/app/src/main/res/layout/item_calendar.xml index f7c4298d..1b0abcfa 100644 --- a/app/src/main/res/layout/item_calendar.xml +++ b/app/src/main/res/layout/item_calendar.xml @@ -1,6 +1,6 @@