Android 使用WheelPicker自定义日期滚轮选择器

本文介绍了如何在Android项目中引入和使用WheelPicker库创建自定义日期时间选择器,包括布局设置、Data的配置、初始值设定以及输出选中时间的方法。
摘要由CSDN通过智能技术生成

效果图

首先放一张最终的效果图

在这里插入图片描述

git地址

https://github.com/AigeStudio/WheelPicker

WheelPicker引入

首先我们需要在对应的build.gradle引入这个库

implementation 'cn.aigestudio.wheelpicker:WheelPicker:1.1.3'

在这里插入图片描述

layout使用(附代码)

在这一步已经可以直接在layout文件中使用,观看一下效果后再根据自己的需求去调整。

这里我就直接上我写好的代码。

<?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="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/pop_up_background_color"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/tvCancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="@dimen/item_dp_28"
            android:text="@string/cl_common_cancel"
            android:textColor="@color/text_main_body_color"
            android:textSize="@dimen/sp_14" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:textColor="@color/tv_title_dark_grey"
            android:textSize="@dimen/sp_17" />

        <TextView
            android:id="@+id/tvConfirm"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:padding="@dimen/item_dp_28"
            android:text="@string/cl_common_confirm"
            android:textColor="@color/text_special_color"
            android:textSize="@dimen/sp_14" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingBottom="@dimen/dp_24"
        android:paddingStart="@dimen/dp_16"
        android:paddingEnd="@dimen/dp_16">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.5"
            android:text="Y"
            android:textSize="@dimen/sp_15"
            android:textColor="@color/text_special_color"
            android:gravity="center"/>

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="M"
            android:textSize="@dimen/sp_15"
            android:textColor="@color/text_special_color"
            android:gravity="center"/>

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="D"
            android:textSize="@dimen/sp_15"
            android:textColor="@color/text_special_color"
            android:gravity="center"/>

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="H"
            android:textSize="@dimen/sp_15"
            android:textColor="@color/text_special_color"
            android:gravity="center"/>

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="M"
            android:textSize="@dimen/sp_15"
            android:textColor="@color/text_special_color"
            android:gravity="center"/>

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.5"
            android:textSize="@dimen/sp_15"
            android:textColor="@color/text_special_color"
            android:gravity="center"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingLeft="@dimen/dp_16"
        android:paddingRight="@dimen/dp_16"
        android:paddingBottom="@dimen/dp_48">

        <com.aigestudio.wheelpicker.widgets.WheelYearPicker
            android:id="@+id/wpYear"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.5"
            app:wheel_item_text_size="@dimen/sp_15"
            app:wheel_item_text_color="@color/text_main_body_color"
            app:wheel_indicator="true"
            app:wheel_indicator_size="@dimen/dp_1"
            app:wheel_indicator_color="@color/text_main_body_color"
            app:wheel_visible_item_count="5"
            app:wheel_item_space="@dimen/dp_16"
            app:wheel_atmospheric="true"/>

        <com.aigestudio.wheelpicker.widgets.WheelMonthPicker
            android:id="@+id/wpMonth"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:wheel_item_text_size="@dimen/sp_15"
            app:wheel_item_text_color="@color/text_main_body_color"
            app:wheel_indicator="true"
            app:wheel_indicator_size="@dimen/dp_1"
            app:wheel_indicator_color="@color/text_main_body_color"
            app:wheel_visible_item_count="5"
            app:wheel_item_space="@dimen/dp_16"
            app:wheel_atmospheric="true"/>

        <com.aigestudio.wheelpicker.widgets.WheelDayPicker
            android:id="@+id/wpDay"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:wheel_item_text_size="@dimen/sp_15"
            app:wheel_item_text_color="@color/text_main_body_color"
            app:wheel_indicator="true"
            app:wheel_indicator_size="@dimen/dp_1"
            app:wheel_indicator_color="@color/text_main_body_color"
            app:wheel_visible_item_count="5"
            app:wheel_item_space="@dimen/dp_16"
            app:wheel_atmospheric="true"/>

        <com.aigestudio.wheelpicker.WheelPicker
            android:id="@+id/wpHour"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:wheel_item_text_size="@dimen/sp_15"
            app:wheel_item_text_color="@color/text_main_body_color"
            app:wheel_indicator="true"
            app:wheel_indicator_size="@dimen/dp_1"
            app:wheel_indicator_color="@color/text_main_body_color"
            app:wheel_visible_item_count="5"
            app:wheel_item_space="@dimen/dp_16"
            app:wheel_atmospheric="true"/>

        <com.aigestudio.wheelpicker.WheelPicker
            android:id="@+id/wpMinute"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:wheel_item_text_size="@dimen/sp_15"
            app:wheel_item_text_color="@color/text_main_body_color"
            app:wheel_indicator="true"
            app:wheel_indicator_size="@dimen/dp_1"
            app:wheel_indicator_color="@color/text_main_body_color"
            app:wheel_visible_item_count="5"
            app:wheel_item_space="@dimen/dp_16"
            app:wheel_atmospheric="true"/>

        <com.aigestudio.wheelpicker.WheelPicker
            android:id="@+id/wpNoon"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1.5"
            app:wheel_item_text_size="@dimen/sp_15"
            app:wheel_item_text_color="@color/text_main_body_color"
            app:wheel_indicator="true"
            app:wheel_indicator_size="@dimen/dp_1"
            app:wheel_indicator_color="@color/text_main_body_color"
            app:wheel_visible_item_count="5"
            app:wheel_item_space="@dimen/dp_16"
            app:wheel_atmospheric="true"/>

    </LinearLayout>


</LinearLayout>

我这里是使用了6个WheelPicker

其中的 颜色文件color 和 占宽比重 大家可以根据自己的需求去定,下面我对部分代码进行详解:

	// 这个是选中item的上下两根线,true为显示,false为去掉
	app:wheel_indicator="true"
	
	//size是线的粗线
	app:wheel_indicator_size="@dimen/dp_1"
	
	//color是线的颜色
   	app:wheel_indicator_color="@color/text_main_body_color"
	//这个是总共显示的item数
	app:wheel_visible_item_count="5"
	
	//两个item之间间隔的距离
    app:wheel_item_space="@dimen/dp_16"
    
    //是否加入渐变色,这里会按照你设置的item文字颜色,越靠近两边颜色越淡
    app:wheel_atmospheric="true"

WheelPicker的Data设置

这里的年月日是使用了WheelPicker自带的年月日picker,所以Data已经自动设置为年份和月份还有天数的对应数据。
至于后面的Hour、Minute、AM or PM这个的数据则需要我们自己写入

		//初始化Hour数据 (0-11)
        val listOfHour = (0..11).map { number ->
            if (number < 10) "0$number" else number.toString()
        }
        wpHour.data = listOfHour
        
        //初始化Minute数据 (0-59)
        val listOfMinute = (0..59).map { number ->
            if (number < 10) "0$number" else number.toString()
        }
        wpMinute.data = listOfMinute
        
        //初始化noon
        wpNoon.data = listOf("AM", "PM")

如果大家不想写AM、PM这一栏也可以直接在Hour处使用 0-23 来显示

Select的初始值设置

我们在设置完所有对应的data后,其实就已经和效果图的展示一样了。

但是我们正常使用的时候是需要带参去初始化显示,去给它赋一个值来显示,下面就是我给它赋值的一个过程。

首先我写了个带所有需要使用到的参数的方法

// 传入日期时间设置
    fun setInitialDateTime(year: Int, month: Int, day: Int, hour: Int, minute: Int, isAM: Boolean) {
        //初始化Hour数据
        val listOfHour = (0..12).map { number ->
            if (number < 10) "0$number" else number.toString()
        }
        wpHour.data = listOfHour
        //初始化Minute数据
        val listOfMinute = (0..59).map { number ->
            if (number < 10) "0$number" else number.toString()
        }
        wpMinute.data = listOfMinute
        //初始化noon
        wpNoon.data = listOf("AM", "PM")

        //设置年份
        wpYear.selectedYear = year
        //设置月份
        wpMonth.selectedMonth = month
        //设置天
        wpDay.month = month
        wpDay.selectedDay = day
        //设置小时
        wpHour.setSelectedItemPosition(hour,false)
        //设置分钟
        wpMinute.setSelectedItemPosition(minute,false)
        //设置早上晚上
        wpNoon.setSelectedItemPosition(if (isAM) 0 else 1, false)
    }

将一个指定的字符串,(例:2024/04/24 16:18) 传入,这里可以获取当前的时间去传入,就可以显示当前的日期和时间。

		//填充默认时间
        val currentDateTime = Calendar.getInstance()
        val year = currentDateTime.get(Calendar.YEAR)
        val month = currentDateTime.get(Calendar.MONTH) + 1
        val day = currentDateTime.get(Calendar.DAY_OF_MONTH)
        val hour = currentDateTime.get(Calendar.HOUR_OF_DAY)
        val minute = currentDateTime.get(Calendar.MINUTE)

        val formattedDateTime = String.format("%04d/%02d/%02d %02d:%02d", year, month, day, hour, minute)

这里我是因为在界面上有显示对应时间,所以仅在第一次进入界面初始化的时候去拿了当前时间使用,后面都是用的选择后的时间(因为我在点击确认后就会显示新的选中时间)。

			val formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm")
            val dateTime = LocalDateTime.parse(str, formatter)

            val mDateSelectDialog = CustomDateSelectDialog(activity as AppCompatActivity)
            val year = dateTime.year
            val month = dateTime.monthValue
            val day = dateTime.dayOfMonth
            var hour = dateTime.hour
            var isAm = true
            if (hour > 12) {
                isAm = false
                hour -= 12
            }
            val minute = dateTime.minute
            mDateSelectDialog.setInitialDateTime(year,month,day,hour,minute,isAm)
            mDateSelectDialog.setTouchOutSide(true)
            mDateSelectDialog.setConfirmFilterListener {
                csiDate.setRightText(it, false)
            }

输出选中的时间

这里因为我是做成一个popupWindow,也就是弹出框的形式,所以我在确定编辑数据后还会将它以一个字符串的形式返回到界面显示。

		//点击确认按钮
        tvConfirm.setOnClickListener {
            //确认最终编辑的数据
            val selYear = wpYear.currentYear
            val selMonth = wpMonth.currentMonth
            val selDay = wpDay.currentDay
            var selHour = wpHour.currentItemPosition
            val selMinute = wpMinute.currentItemPosition
            val isAM = wpNoon.currentItemPosition == 0
            if (!isAM) {
                selHour += 12
            }
            val dateStr = String.format("%04d/%02d/%02d %02d:%02d", selYear, selMonth, selDay, selHour, selMinute)
        }

这里拿到最终的dateStr数据进行显示就可以了,我在这里是写了个回调在后面,与这篇的内容关系不大,在这里就不写上了,大家自己根据数据进行处理就好。

小结

完成了UI设计图所需的日期时间选择器效果,写个笔记顺便可以记录和复盘一下过程。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值