自定义仿日历组件弹框
可以选择区间,不区分点击日期前后,添加简易版阳历转农历,从第三方免费接口获取节假日,定义扩展定义排班信息标签
创建LunarCalendarDialog
底部弹框
typescript
class LunarCalendarDialog(
context: Context,
private val listener: OnDateRangeSelectedListener,
private val initialStartDate: Date? = null,
private val initialEndDate: Date? = null,
private var holidayData: Map<String, HolidayInfo>? = null,
private val scheduleData: Map<String, ScheduleInfo>? = null,
)
scss
// 启动协程获取当年节假日数据
CoroutineScope(Dispatchers.Main).launch {
val year = Calendar.getInstance().get(Calendar.YEAR)
val fetchedHolidays = try {
val fetchedHolidays = LunarCalendarNetUtil.fetchYearHolidayMap(year)
// val fetchedNextYearHolidays = LunarCalendarNetUtil.fetchYearHolidayMap(year + 1)
// fetchedHolidays + fetchedNextYearHolidays
fetchedHolidays
} catch (e: Exception) {
e.printStackTrace()
mutableMapOf<String, LunarCalendarDialog.HolidayInfo>()
}
holidayData = fetchedHolidays // 更新节假日数据
initMonthsData() // 重新初始化月份数据,应用新的节假日
monthsAdapter.notifyDataSetChanged() // 刷新UI
}
通过LunarCalendarNetUtil
获取节假日数据
kotlin
private const val HOLIDAY_API_URL = "https://timor.tech/api/holiday/year/"
kotlin
private fun parseHolidayResponse(json: String): Map<String, LunarCalendarDialog.HolidayInfo> {
val holidayMap = mutableMapOf<String, LunarCalendarDialog.HolidayInfo>()
val jsonObject = JSONObject(json)
// 检查接口返回状态(code=0 表示成功)
if (jsonObject.getInt("code") == 0) {
val data = jsonObject.getJSONObject("holiday")
data.keys().forEachRemaining { key ->
val dayObj = data.getJSONObject(key)
val date = dayObj.getString("date") // 格式:yyyy-MM-dd
val name = dayObj.getString("name")
val isHoliday = dayObj.getBoolean("holiday") // 是否为法定节假日
holidayMap[date] = LunarCalendarDialog.HolidayInfo(name, isHoliday)
}
} else {
Log.e(TAG, "接口返回错误:${jsonObject.getString("msg")}")
}
return holidayMap
}
通过LunarConverter
工具获取阳历日期对应的农历日期,也可以寻找其他库替代
kotlin
fun getLunarDateString(calendar: Calendar): String {
val year = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH) + 1 // 注意Calendar的月份是从0开始的
val day = calendar.get(Calendar.DAY_OF_MONTH)
println("今天阳历是: $year 年$month 月$day 日")
val lunarDate = solarToLunar(year, month, day)
println("对应的农历是: $lunarDate")
val lunarDateArrayEnd = lunarDate.split(" ")[1]
val dayName = lunarDateArrayEnd.substring(lunarDateArrayEnd.indexOf("月") + 1)
if (dayName == "初一") {
return lunarDateArrayEnd.substring(0, lunarDateArrayEnd.indexOf("月") + 1)
}
return dayName
}
使用方法
kotlin
// 获取排班数据
val scheduleData = mapOf(
"2026-01-05" to LunarCalendarDialog.ScheduleInfo("早班", "08:00-16:00"),
"2026-01-06" to LunarCalendarDialog.ScheduleInfo("中班", "16:00-24:00"),
// 更多排班数据...
)
// 显示日历弹窗
val dialog = LunarCalendarDialog(
context = this,
listener = object : LunarCalendarDialog.OnDateRangeSelectedListener {
override fun onDateRangeSelected(startDate: Date, endDate: Date) {
// 处理选择的日期范围
val format = SimpleDateFormat("yyyy-MM-dd", Locale.CHINA)
Toast.makeText(
this@MainActivity,
"开始日期: ${format.format(startDate)}\n结束日期: ${format.format(endDate)}",
Toast.LENGTH_SHORT
).show()
}
},
scheduleData = scheduleData
)
findViewById<MaterialButton>(R.id.calendar_button).setOnClickListener {
dialog.show()
}
展示效果
