Initial commit - v1.1.9
This commit is contained in:
238
app/src/main/java/com/example/shiftalarm/CalendarAdapter.kt
Normal file
238
app/src/main/java/com/example/shiftalarm/CalendarAdapter.kt
Normal file
@@ -0,0 +1,238 @@
|
||||
package com.example.shiftalarm
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import java.time.LocalDate
|
||||
|
||||
data class DayShift(
|
||||
val date: LocalDate?,
|
||||
val shift: String?,
|
||||
val hasMemo: Boolean = false,
|
||||
val memoContent: String? = null
|
||||
)
|
||||
|
||||
class CalendarAdapter(
|
||||
var days: List<DayShift>,
|
||||
private val listener: OnDayClickListener,
|
||||
var showHolidays: Boolean = true
|
||||
) : RecyclerView.Adapter<CalendarAdapter.ViewHolder>() {
|
||||
|
||||
interface OnDayClickListener {
|
||||
fun onDayClick(date: LocalDate, currentShift: String)
|
||||
}
|
||||
|
||||
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val root: View = view.findViewById(R.id.dayRoot)
|
||||
val dayNumber: TextView = view.findViewById(R.id.dayNumber)
|
||||
val shiftChar: TextView = view.findViewById(R.id.shiftChar)
|
||||
val holidayNameSmall: TextView = view.findViewById(R.id.holidayNameSmall)
|
||||
val memoIndicator: ImageView = view.findViewById(R.id.memoIndicator)
|
||||
val tvTide: TextView = view.findViewById(R.id.tvTide)
|
||||
val memoContent: TextView = view.findViewById(R.id.memoContent)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_day, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
private fun dpToPx(context: Context, dp: Float): Int {
|
||||
return (dp * context.resources.displayMetrics.density).toInt()
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = days[position]
|
||||
val context = holder.itemView.context
|
||||
|
||||
if (item.date == null) {
|
||||
holder.itemView.visibility = View.INVISIBLE
|
||||
return
|
||||
}
|
||||
|
||||
holder.itemView.visibility = View.VISIBLE
|
||||
|
||||
// Day Number
|
||||
holder.dayNumber.text = item.date.dayOfMonth.toString()
|
||||
|
||||
// Holiday / Weekend logic
|
||||
val isSunday = item.date.dayOfWeek == java.time.DayOfWeek.SUNDAY
|
||||
val isSaturday = item.date.dayOfWeek == java.time.DayOfWeek.SATURDAY
|
||||
val fullHolidayName = HolidayManager.getHolidayName(item.date)
|
||||
val isToday = item.date == LocalDate.now()
|
||||
|
||||
// Day Number Color
|
||||
if (fullHolidayName != null || isSunday) {
|
||||
holder.dayNumber.setTextColor(Color.parseColor("#FF5252"))
|
||||
} else if (isSaturday) {
|
||||
holder.dayNumber.setTextColor(Color.parseColor("#448AFF"))
|
||||
} else {
|
||||
holder.dayNumber.setTextColor(ContextCompat.getColor(context, R.color.text_primary))
|
||||
}
|
||||
|
||||
// Tide Display
|
||||
val prefs = context.getSharedPreferences("ShiftAlarmPrefs", Context.MODE_PRIVATE)
|
||||
val showTide = prefs.getBoolean("show_tide", false)
|
||||
val tideLocation = prefs.getString("selected_tide_location", "군산") ?: "군산"
|
||||
|
||||
if (showTide) {
|
||||
val tide = HolidayManager.getTide(item.date, tideLocation)
|
||||
if (tide.isNotEmpty()) {
|
||||
holder.tvTide.visibility = View.VISIBLE
|
||||
holder.tvTide.text = tide
|
||||
} else {
|
||||
holder.tvTide.visibility = View.GONE
|
||||
}
|
||||
} else {
|
||||
holder.tvTide.visibility = View.GONE
|
||||
}
|
||||
|
||||
|
||||
// --- Shift & Holiday Display Logic ---
|
||||
holder.shiftChar.background = null
|
||||
holder.shiftChar.text = ""
|
||||
holder.holidayNameSmall.visibility = View.GONE
|
||||
holder.shiftChar.textSize = 13f
|
||||
|
||||
// "반월", "반년" (Half-Monthly, Half-Yearly) Special Logic
|
||||
// These are overrides or specific shifts that user sets.
|
||||
// User requested: "월", "년" text. Half-filled background (Red + Transparent).
|
||||
// Check exact string or "startswith" if logic changed?
|
||||
// Logic in adapter `getShift` might return "반월", "반년".
|
||||
|
||||
if (showHolidays && fullHolidayName != null) {
|
||||
// Holiday Mode (Priority): Show full holiday name, no circle
|
||||
holder.shiftChar.text = fullHolidayName
|
||||
holder.shiftChar.setTextColor(Color.parseColor("#FF5252"))
|
||||
holder.shiftChar.textSize = 10f
|
||||
holder.shiftChar.background = null
|
||||
} else if (item.shift != null && item.shift != "비번") {
|
||||
// Shift Mode
|
||||
|
||||
// Handle specific "Half" cases first
|
||||
if (item.shift == "반월" || item.shift == "반년") {
|
||||
holder.shiftChar.text = if (item.shift == "반월") "월" else "년"
|
||||
holder.shiftChar.setTextColor(ContextCompat.getColor(context, R.color.black)) // Black for contrast on Half Red/Transparent
|
||||
holder.shiftChar.textSize = 13f
|
||||
holder.shiftChar.background = ContextCompat.getDrawable(context, R.drawable.bg_shift_half_red)
|
||||
} else {
|
||||
// Standard Logic
|
||||
val shiftAbbreviation = when (item.shift) {
|
||||
"주간" -> "주"
|
||||
"석간" -> "석"
|
||||
"야간" -> "야"
|
||||
"주간 맞교대" -> "주맞"
|
||||
"야간 맞교대" -> "야맞"
|
||||
"휴무", "휴가" -> "휴"
|
||||
"월차" -> "월"
|
||||
"연차" -> "연"
|
||||
"교육" -> "교"
|
||||
else -> item.shift.take(1)
|
||||
}
|
||||
holder.shiftChar.text = shiftAbbreviation
|
||||
holder.shiftChar.textSize = 15f
|
||||
holder.shiftChar.setTypeface(null, android.graphics.Typeface.BOLD)
|
||||
|
||||
val shiftColorRes = when (item.shift) {
|
||||
"주간" -> R.color.shift_lemon
|
||||
"석간" -> R.color.shift_seok
|
||||
"야간" -> R.color.shift_ya
|
||||
"주간 맞교대" -> R.color.shift_jumat
|
||||
"야간 맞교대" -> R.color.shift_yamat
|
||||
"휴무", "휴가", "월차", "연차" -> R.color.shift_red
|
||||
"교육" -> R.color.primary
|
||||
else -> R.color.text_secondary
|
||||
}
|
||||
val shiftColor = ContextCompat.getColor(context, shiftColorRes)
|
||||
|
||||
if (isToday) {
|
||||
// Today: Solid Circle
|
||||
val background = ContextCompat.getDrawable(context, R.drawable.bg_shift_solid_v4) as? android.graphics.drawable.GradientDrawable
|
||||
background?.setColor(shiftColor)
|
||||
holder.shiftChar.background = background
|
||||
holder.shiftChar.backgroundTintList = null
|
||||
|
||||
if (item.shift == "주간" || item.shift == "석간") {
|
||||
holder.shiftChar.setTextColor(ContextCompat.getColor(context, R.color.black))
|
||||
} else {
|
||||
holder.shiftChar.setTextColor(Color.WHITE)
|
||||
}
|
||||
} else {
|
||||
// Not Today: Stroke Circle
|
||||
val background = ContextCompat.getDrawable(context, R.drawable.bg_shift_stroke_v4) as? android.graphics.drawable.GradientDrawable
|
||||
background?.setStroke(dpToPx(context, 1.5f), shiftColor)
|
||||
background?.setColor(Color.TRANSPARENT)
|
||||
|
||||
holder.shiftChar.background = background
|
||||
holder.shiftChar.backgroundTintList = null
|
||||
|
||||
holder.shiftChar.setTextColor(shiftColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lunar date small display if requested or just default
|
||||
if (!showHolidays && fullHolidayName != null) {
|
||||
holder.holidayNameSmall.visibility = View.VISIBLE
|
||||
holder.holidayNameSmall.text = fullHolidayName
|
||||
} else {
|
||||
// Ensure visibility GONE if not needed (e.g. standard day)
|
||||
holder.holidayNameSmall.visibility = View.GONE
|
||||
}
|
||||
|
||||
// Double check: if showHolidays=true (Holiday mode), we handled it at top block.
|
||||
// But if showHolidays=true and NO holiday, we show lunar date?
|
||||
// User asked: "Overlap date and holiday text".
|
||||
// My item_day.xml has holidayNameSmall at bottom now.
|
||||
// If showHolidays=true, CalendarAdapter usually HIDES shiftChar and shows Holiday Name?
|
||||
// Wait, standard logic (lines 84-91 above):
|
||||
// If showHolidays && fullHolidayName != null -> shiftChar shows Name.
|
||||
// If showHolidays && fullHolidayName == null -> shiftChar shows LUNAR DATE? (Old logic had this).
|
||||
|
||||
if (showHolidays && fullHolidayName == null) {
|
||||
// Show Lunar Date in shiftChar instead of empty?
|
||||
// Or shiftChar is empty, show small text?
|
||||
// Previous code:
|
||||
// holder.shiftChar.text = ""
|
||||
// holder.holidayNameSmall.visibility = View.VISIBLE
|
||||
// holder.holidayNameSmall.text = HolidayManager.getLunarDateString(item.date)
|
||||
|
||||
holder.shiftChar.text = HolidayManager.getLunarDateString(item.date)
|
||||
holder.shiftChar.textSize = 10f
|
||||
holder.shiftChar.setTextColor(ContextCompat.getColor(context, R.color.text_tertiary))
|
||||
holder.shiftChar.background = null
|
||||
}
|
||||
|
||||
|
||||
// Memo Indicator
|
||||
holder.memoIndicator.visibility = View.GONE // Hide indicator, showing text instead
|
||||
if (item.hasMemo && !item.memoContent.isNullOrEmpty()) {
|
||||
holder.memoContent.visibility = View.VISIBLE
|
||||
holder.memoContent.text = item.memoContent
|
||||
} else {
|
||||
holder.memoContent.visibility = View.GONE
|
||||
}
|
||||
|
||||
// Today Border or Highlight
|
||||
if (isToday) {
|
||||
holder.root.setBackgroundResource(R.drawable.bg_grid_cell_today_v4)
|
||||
} else {
|
||||
holder.root.setBackgroundResource(R.drawable.bg_grid_cell_v4)
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener {
|
||||
if (item.date != null && item.shift != null) {
|
||||
listener.onDayClick(item.date, item.shift)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = days.size
|
||||
}
|
||||
Reference in New Issue
Block a user