| SU | MO | Tu | We | Th | Fr | Sa |
|---|
styles
<style name="WeekDayText">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">48dp</item>
<item name="android:layout_weight">1</item>
<item name="android:gravity">center</item>
<item name="android:textSize">16sp</item>
</style>
R.layout.week_picker
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/weekViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
R.layout.week_item
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal"
android:padding="8dp">
<TextView
android:id="@+id/sundayView"
style="@style/WeekDayText"
android:text="日" />
<TextView
android:id="@+id/mondayView"
style="@style/WeekDayText"
android:text="一" />
<!-- 周二到周五 -->
<TextView
android:id="@+id/tuesdayView"
style="@style/WeekDayText"
android:text="二" />
<TextView
android:id="@+id/wednesdayView"
style="@style/WeekDayText"
android:text="三" />
<TextView
android:id="@+id/thursdayView"
style="@style/WeekDayText"
android:text="四" />
<TextView
android:id="@+id/fridayView"
style="@style/WeekDayText"
android:text="五" />
<TextView
android:id="@+id/saturdayView"
style="@style/WeekDayText"
android:text="六" />
</LinearLayout>
WeekPicker
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import global.xfinite.conso.library.R
import global.xfinite.conso.logtool.LogTool
import java.text.SimpleDateFormat
import java.util.*
class WeekPicker @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
private val viewPager: ViewPager2
private var selectedDate = Calendar.getInstance()
private var onDateSelectedListener: ((Date) -> Unit)? = null
init {
LayoutInflater.from(context).inflate(R.layout.week_picker, this, true)
viewPager = findViewById(R.id.weekViewPager)
setupViewPager()
}
private fun setupViewPager() {
viewPager.adapter = WeekPagerAdapter()
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
// 计算当前显示的周
val weekOffset = position - Int.MAX_VALUE / 2
selectedDate = getCalendarForWeek(weekOffset)
onDateSelectedListener?.invoke(selectedDate.time)
}
})
// 设置初始位置为中间,实现无限滑动
viewPager.setCurrentItem(Int.MAX_VALUE / 2, false)
}
fun setOnDateSelectedListener(listener: (Date) -> Unit) {
this.onDateSelectedListener = listener
}
private fun getCalendarForWeek(weekOffset: Int): Calendar {
val calendar = Calendar.getInstance().apply {
firstDayOfWeek = Calendar.SUNDAY
}
calendar.add(Calendar.WEEK_OF_YEAR, weekOffset)
return calendar
}
private inner class WeekPagerAdapter : RecyclerView.Adapter<WeekViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WeekViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.week_item, parent, false)
return WeekViewHolder(view)
}
override fun onBindViewHolder(holder: WeekViewHolder, position: Int) {
val weekOffset = position - Int.MAX_VALUE / 2
val calendar = getCalendarForWeek(weekOffset)
// 设置周日到周六的日期
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
holder.bindWeek(calendar)
}
override fun getItemCount(): Int = Int.MAX_VALUE
}
private inner class WeekViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val dayViews = listOf(
itemView.findViewById<TextView>(R.id.sundayView),
itemView.findViewById<TextView>(R.id.mondayView),
itemView.findViewById<TextView>(R.id.tuesdayView),
itemView.findViewById<TextView>(R.id.wednesdayView),
itemView.findViewById<TextView>(R.id.thursdayView),
itemView.findViewById<TextView>(R.id.fridayView),
itemView.findViewById<TextView>(R.id.saturdayView)
)
fun bindWeek(startOfWeek: Calendar) {
val dateFormat = SimpleDateFormat("d", Locale.getDefault())
// 创建一个包含整周日期的列表
val weekDays = (0 until 7).map { dayOffset ->
val dayCalendar = startOfWeek.clone() as Calendar
dayCalendar.add(Calendar.DAY_OF_YEAR, dayOffset)
dayCalendar to dateFormat.format(dayCalendar.time)
}
dayViews.forEachIndexed { index, textView ->
val (dayCalendar, dayText) = weekDays[index]
// 设置日期文本
textView.text = dayText
// 设置点击事件
textView.setOnClickListener {
selectedDate = dayCalendar.clone() as Calendar
highlightSelectedDay(index)
onDateSelectedListener?.invoke(selectedDate.time)
LogTool.d("WeekPicker", "Selected date: ${SimpleDateFormat("yyyy-MM-dd").format(selectedDate.time)}")
}
// 高亮选中的日期
if (dayCalendar.get(Calendar.DAY_OF_YEAR) == selectedDate.get(Calendar.DAY_OF_YEAR) &&
dayCalendar.get(Calendar.YEAR) == selectedDate.get(Calendar.YEAR)) {
highlightSelectedDay(index)
} else {
resetDayStyle(textView)
}
}
}
private fun highlightSelectedDay(selectedIndex: Int) {
dayViews.forEachIndexed { index, textView ->
if (index == selectedIndex) {
textView.setTextColor(ContextCompat.getColor(context, android.R.color.white))
textView.background = ContextCompat.getDrawable(context, R.drawable.border_r8_left_44d564_radius)
} else {
resetDayStyle(textView)
}
}
}
private fun resetDayStyle(textView: TextView) {
textView.setTextColor(ContextCompat.getColor(context, android.R.color.black))
textView.background = null
}
}
}
<your.path.WeekPicker
android:id="@+id/weekViewPagerLayout"
android:layout_width="match_parent"
android:layout_height="50dp"/>
val weekPicker = binding.weekViewPagerLayout
weekPicker.setOnDateSelectedListener { selectedDate ->
// 处理日期选择
LogTool.d("WeekPicker", "Selected date: $selectedDate")
}