feat(live-reservation-all): 주간 캘린더 라이브러리 제거 및 개별 구현
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user