美文网首页Android收藏
Android自定义时间选择弹窗

Android自定义时间选择弹窗

作者: itfitness | 来源:发表于2022-02-09 16:05 被阅读0次

    目录

    效果展示

    实现步骤

    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

    相关文章

      网友评论

        本文标题:Android自定义时间选择弹窗

        本文链接:https://www.haomeiwen.com/subject/kxwwkrtx.html