Android收藏

Android自定义时间选择弹窗

2022-02-09  本文已影响0人  itfitness

目录

效果展示

实现步骤

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

上一篇下一篇

猜你喜欢

热点阅读