目录
![](https://img.haomeiwen.com/i8850933/81b67b8cf8598883.png)
效果展示
![](https://img.haomeiwen.com/i8850933/8449ba1258c42771.gif)
实现步骤
1.NumberPicker的使用
这里我们使用系统控件NumberPicker来组合实现,因此首先介绍下NumberPicker的使用,下面展示几个重要的设置:
setDescendantFocusability:设置为对当前值是否可编辑,默认为可编辑,DatePicker.FOCUS_BLOCK_DESCENDANTS为不可编辑
setWrapSelectorWheel:设置是否循环显示
setMaxValue:设置最大值
setMinValue:设置最小值
setValue:设置当前值
setFormatter:设置格式化器
setOnValueChangedListener:设置值变化时的监听
2.组合NumberPicker
懂得了NumberPicker的基本使用然后接下来就是对于NumberPicker的组合了,这里也比较简单具体布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@color/white"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="请选择时间"
android:layout_gravity="center_horizontal"
android:textColor="@color/black"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tvOk"
android:text="确定"
android:layout_gravity="center_vertical|right"
android:textColor="@color/purple_500"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/tvCancel"
android:text="取消"
android:layout_gravity="center_vertical|left"
android:textColor="@color/purple_500"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<NumberPicker
android:id="@+id/numberPickerYear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants" />
<TextView
android:text="年"
android:textSize="14sp"
android:layout_gravity="center_vertical"
android:textColor="@color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<NumberPicker
android:id="@+id/numberPickerMonth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants" />
<TextView
android:text="月"
android:textSize="14sp"
android:layout_gravity="center_vertical"
android:textColor="@color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<NumberPicker
android:id="@+id/numberPickerDay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants" />
<TextView
android:text="日"
android:textSize="14sp"
android:layout_gravity="center_vertical"
android:textColor="@color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<NumberPicker
android:id="@+id/numberPickerHour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants" />
<TextView
android:text="时"
android:textSize="14sp"
android:layout_gravity="center_vertical"
android:textColor="@color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<NumberPicker
android:id="@+id/numberPickerMinute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants" />
<TextView
android:text="分"
android:textSize="14sp"
android:layout_gravity="center_vertical"
android:textColor="@color/black"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
3.数据设置与处理
最后便是对显示的年、月、日、时、分的数据处理了,首先是年,这里我们取的最小值是当前年往前10年,最大值是当前年,由于有些年的2月份天数不一定相同因此我们设置了值改变的监听事件,当年发生改变并且选择的月是2月份的时候,就重新计算下天数
//初始化年选择器
val currentYear = calendar.get(Calendar.YEAR)
numberPickerYear.apply {
minValue = currentYear - 10
maxValue = currentYear
value = currentYear
//不循环滚动
wrapSelectorWheel = false
//当年发生改变的时候要重新设置当前选择的天数(因为有的2月份是29天)
setOnValueChangedListener { picker, oldVal, newVal ->
calendar.set(Calendar.YEAR,newVal)
val currentMonth = calendar.get(Calendar.MONTH) + 1
//如果当前是二月份才重新设置
if(currentMonth == 2){
numberPickerDay.apply {
minValue = 1
maxValue = calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
value = value.coerceAtMost(calendar.getActualMaximum(Calendar.DAY_OF_MONTH))
}
}
}
}
然后是月,月的数据设置就相对简单,最小值设为1,最大值设为12即可,然后同样的是需要设置值改变的监听,因为月的天数不一定相同,另外在这里还加了个格式化器(当数值小于10 的时候在前面加0对齐),代码如下:
//初始化月份选择器
val currentMonth = calendar.get(Calendar.MONTH) + 1
numberPickerMonth.apply {
minValue = 1
maxValue = 12
value = currentMonth
setFormatter {
if (it < 10){
"0$it"
}else{
"$it"
}
}
//当前月份发生改变的时候,调整选择的天数,(因为月份有30天、31天、28/29天)
setOnValueChangedListener { picker, oldVal, newVal ->
calendar.set(Calendar.MONTH,newVal - 1)
numberPickerDay.apply {
minValue = 1
maxValue = calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
value = value.coerceAtMost(calendar.getActualMaximum(Calendar.DAY_OF_MONTH))
}
}
}
然后是天和时、分,这三个比较简单因为代码如下:
//初始化天选择器
val currentDay = calendar.get(Calendar.DAY_OF_MONTH)
numberPickerDay.apply {
minValue = 1
maxValue = calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
value = currentDay
//当值小于10的时候在前面加个0
setFormatter {
if (it < 10){
"0$it"
}else{
"$it"
}
}
}
//初始化小时选择器
val currentHour = calendar.get(Calendar.HOUR_OF_DAY)
numberPickerHour.apply {
minValue = 0
maxValue = 23
value = currentHour
setFormatter {
if (it < 10){
"0$it"
}else{
"$it"
}
}
}
//初始化分钟选择器
val currentMinute = calendar.get(Calendar.MINUTE)
numberPickerMinute.apply {
minValue = 0
maxValue = 59
value = currentMinute
setFormatter {
if (it < 10){
"0$it"
}else{
"$it"
}
}
}
案例源码
更详细的代码请下载源码查看:https://gitee.com/itfitness/time-picker
网友评论