news 2026/8/17 17:20:15

如何用 Android-PickerView 快速实现自定义年月日时分秒时间选择器:从零到实战的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何用 Android-PickerView 快速实现自定义年月日时分秒时间选择器:从零到实战的完整指南

如何用 Android-PickerView 快速实现自定义年月日时分秒时间选择器:从零到实战的完整指南

【免费下载链接】Android-PickerViewThis is a picker view for android , support linkage effect, timepicker and optionspicker.(时间选择器、省市区三级联动)项目地址: https://gitcode.com/gh_mirrors/an/Android-PickerView

Android-PickerView 是 Android 开发中非常经典的时间选择器开源库,它把"年、月、日、时、分、秒"每一列都拆成独立滚轮,配合 TimePickerBuilder 的链式调用,你可以自由决定显示哪些时间单位、标签叫什么、弹层长什么样。这篇实战文章会带你从零跑通一个自定义年月日时分秒的时间选择器,并把最常见的坑一次性排干净。

别再被系统时间选择器"锁死"了

假设产品经理丢给你一个需求:预约表单里要一个时间选择器,只显示"年、月、日、时、分",秒不要;标签要用中文;底部弹出;整层颜色还得和 App 主色调一致。

拿着系统自带的 DatePicker 比划两下你就明白了:

  • 它只能选日期,没有时分秒的滚轮,格式被焊死;
  • 样式固定,改标题栏、改颜色基本是痴心妄想;
  • 想限制可选范围,得自己在回调里写校验逻辑,越界了只能弹个 Toast 糊弄用户。

而 Android-PickerView 的思路完全不同。它的每一列单位都是一个 WheelView 滚轮,显示哪几列、每列叫什么名字、用多大字号什么颜色,全部交给 Builder 配置。更狠的是,整个弹层都能替换成你自己的布局文件。

这里还有个现实痛点:这个库早期通过 jcenter 仓库分发,而 jcenter 已于 2021 年正式关闭,compile 'com.contrarywind:Android-PickerView:4.1.9'这条依赖现在大概率拉不下来。别慌,官方 README 给出了明确方案——直接克隆源码,把pickerviewwheelview两个 module 引入工程按需改造。

🚀 三步快速接入一个基础时间选择器

第一步:引入 module。把仓库里的pickerviewwheelview两个目录拷进你的工程,并在settings.gradle中注册:

// settings.gradle include ':app' include ':pickerview' include ':wheelview'

第二步:写最小可用代码。在任意 Activity 里创建一个 TimePickerBuilder 实例,回调里拿到的date就是最终选中的时间:

TimePickerView pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() { @Override public void onTimeSelect(Date date, View v) { Toast.makeText(MainActivity.this, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date), Toast.LENGTH_SHORT).show(); } }).build();

第三步:弹出它。在按钮点击处调用pvTime.show(),一个带"取消/确定"按钮、默认显示完整年月日时分秒的滚轮选择器就弹出来了。

三步搞定基础效果。真正的重头戏在下面——怎么把它调教成业务想要的样子。

进阶技巧拆解:两个入口玩转显示单位与标签

技巧一:用 setType 决定显示哪几列,用 setLabel 决定每列叫什么

这是自定义时间格式最核心的入口。setType接收一个长度固定为 6 的布尔数组,按"年、月、日、时、分、秒"的顺序决定每一列滚轮是否出现。比如只要时分秒:

pvTime = new TimePickerBuilder(this, new OnTimeSelectListener() { /* ... */ }) .setType(new boolean[]{false, false, false, true, true, true}) // 只显示 时 分 秒 .setLabel("", "", "", "时", "分", "秒") // 参数与 type 一一对应 .isCenterLabel(false) // false:每一行都带标签;true:仅中间选中项带 .build();

两个提示:其一,setLabel的六个参数与setType一一对应,被隐藏的单位填什么都不起作用;其二,isCenterLabel默认是 true,改成 false 后每行都会显示"时/分/秒",观感更接近原生 iOS 滚轮。如果标签挤在一起,还能用setTextXOffset(0, 0, 0, 40, 0, -40)对每一列做水平偏移微调。

技巧二:setLayoutRes 整层换肤,连标题栏都自己画

如果连顶部的"取消/确定"都想换成自定义按钮、甚至加个图标,就该请出setLayoutRes了。它接收布局资源 id 和一个回调,你在回调里对布局中的控件做初始化:

pvCustomTime = new TimePickerBuilder(this, new OnTimeSelectListener() { /* ... */ }) .setLayoutRes(R.layout.pickerview_custom_time, new CustomListener() { @Override public void customLayout(View v) { // v 就是自定义布局的根 View final TextView tvSubmit = (TextView) v.findViewById(R.id.tv_finish); ImageView ivCancel = (ImageView) v.findViewById(R.id.iv_cancel); tvSubmit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pvCustomTime.returnData(); // 触发选中回调 pvCustomTime.dismiss(); } }); ivCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pvCustomTime.dismiss(); } }); } }) .build();

这里有个硬性要求:自定义布局里必须保留一个 id 为timepicker的容器,里面按顺序放好 id 分别为yearmonthdayhourminsecond的 WheelView,否则库在 findViewById 阶段直接空指针。标准写法参考app/src/main/res/layout/pickerview_custom_time.xml,照抄改样式最稳妥。

⚠️ 避坑指南:这几个雷我替你先踩了

坑一:Calendar 的月份从 0 开始。setRangDate(startDate, endDate)限制范围时,startDate.set(2024, 1, 1)代表的其实是 2024 年 2 月!月份取值 0–11,想设 1 月必须写set(2024, 0, 1)。官方在 demo 里专门用注释强调过这件事。

坑二:setItemVisibleCount 传偶数会被自动加一。"最大可见条目数"建议传 3、5、7、9 这样的奇数,传 6 实际会变成 7。这不是 bug,是滚轮需要保证中心对称,源码注释写得很明白。

坑三:自定义布局忘保留固定 id,运行直接崩溃。前面强调过,timepicker容器和六个 WheelView 的 id 一个都不能少、不能改名。自定义布局最安全的姿势,就是复制 demo 里的 layout 再改视觉样式。

坑四:想要底部弹出得配合 Dialog 模式。默认是居中弹出。想实现 iOS 那种底部弹层,需要isDialog(true)之后再拿到 Dialog 的 Window,设置Gravity.BOTTOM和进出场动画,demo 里的initTimePicker()有完整写法,直接抄。

完整实战整合:做一个"预约上门时间"选择器

把上面的技巧揉进一个真实业务:上门维修预约,需要选择"今天到明年年底"之间的任意时间,精确到分钟即可,标签用中文,主题色用品牌绿。整合后的完整代码如下:

Calendar startDate = Calendar.getInstance(); // 起点:今天 Calendar endDate = Calendar.getInstance(); // 终点:明年年底 endDate.set(Calendar.YEAR, endDate.get(Calendar.YEAR) + 1); endDate.set(Calendar.MONTH, 11); // 12月 endDate.set(Calendar.DAY_OF_MONTH, 31); pvReserve = new TimePickerBuilder(this, new OnTimeSelectListener() { @Override public void onTimeSelect(Date date, View v) { tvResult.setText(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(date)); } }) .setType(new boolean[]{true, true, true, true, true, false}) // 隐藏秒 .setLabel("年", "月", "日", "时", "分", "") .setDate(Calendar.getInstance()) // 默认选中当前时间 .setRangDate(startDate, endDate) // 限制可选范围 .setContentTextSize(18) // 滚轮文字大小 .setDividerColor(0xFF24AD9D) // 分割线品牌色 .setTextColorCenter(0xFF24AD9D) // 选中项品牌色 .setLineSpacingMultiplier(1.6f) // 行间距倍数 .isCyclic(true) // 允许循环滚动 .build(); pvReserve.show();

跑起来你会发现:秒列消失、范围限制生效、每列标签都是中文、选中项和分割线统一成品牌绿。这正是 Android-PickerView 自定义年月日时分秒时间选择器最典型的实战形态。

经验沉淀与延伸

回顾整个自定义过程,其实就是在回答三个问题:显示哪些列(setType)、每列叫什么(setLabel)、弹层长什么样(setLayoutRes 加上颜色字号这一串方法)。想清楚这三点,任何时间选择需求都能拆解成几行链式调用,思路瞬间清晰。

想继续深入,可以从这几处源码下手:

  • 看 demo 的app/src/main/java/com/bigkoo/pickerviewdemo/MainActivity.java,农历模式(setLunarCalendar)、Dialog 底部弹出、夜间主题的写法都在里面;
  • 研究pickerview/src/main/java/com/bigkoo/pickerview/builder/TimePickerBuilder.java,所有可配置方法与其注释都在这个文件里,是最好的"参数词典";
  • 如果业务还需要省市区三级联动,就看OptionsPickerBuilderapp/src/main/assets/province.json的解析示例,思路同源。

动手最快的路径,是把仓库git clone https://gitcode.com/gh_mirrors/an/Android-PickerView拉到本地,跑一遍官方 demo,再对照本文把参数逐个改着玩。源码永远是最好的老师,等你在自己的项目里把它调出想要的效果时,这套自定义思路就真正属于你了。

【免费下载链接】Android-PickerViewThis is a picker view for android , support linkage effect, timepicker and optionspicker.(时间选择器、省市区三级联动)项目地址: https://gitcode.com/gh_mirrors/an/Android-PickerView

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/17 17:19:56

Ubuntu中文输入法配置指南:IBus与Fcitx5对比与实战

1. 从“打不出字”到“行云流水”:Ubuntu中文输入法入门刚装好Ubuntu,桌面清爽,命令行强大,一切都那么美好,直到你需要写一封中文邮件、在浏览器里搜索中文资料,或者给代码写个中文注释——然后发现&#x…

作者头像 李华
网站建设 2026/8/17 17:17:30

2048 AI助手上手实测:从命令行自动代打到算法原理一次讲透

2048 AI助手上手实测:从命令行自动代打到算法原理一次讲透 【免费下载链接】2048-ai AI for the 2048 game 项目地址: https://gitcode.com/gh_mirrors/20/2048-ai 你可能已经玩腻了 2048,但你未必试过让一台机器替你把它打穿。今天要聊的开源项目…

作者头像 李华
网站建设 2026/8/17 17:15:32

工程实践:如何为开发工作流集成稳定可靠的LLM替代服务

在实际开发和学习过程中,我们经常需要借助大型语言模型(LLM)来辅助代码编写、问题排查、技术方案设计或学习新概念。然而,直接访问某些官方服务可能会遇到网络延迟、服务不稳定或访问限制等问题。因此,寻找稳定、快速且…

作者头像 李华
网站建设 2026/8/17 17:08:33

Python基础6 - 字符串:(2)字符串常用操作

目录 一. 拼接 二. 计算字符串长度 三. 截取字符串 (一)普通截取 (二)反向输出字符串 四. 分割、合并字符串 (一)分割字符串 (二)合并字符串 五. 检索字符串 (一…

作者头像 李华
网站建设 2026/8/17 17:02:48

象棋AI助手免费神器:VinXiangQi让棋盘识别与引擎分析一步到位

象棋AI助手免费神器:VinXiangQi让棋盘识别与引擎分析一步到位 【免费下载链接】VinXiangQi Xiangqi syncing tool based on Yolov5 / 基于Yolov5的中国象棋连线工具 项目地址: https://gitcode.com/gh_mirrors/vi/VinXiangQi 在人工智能越来越普及的今天&…

作者头像 李华
网站建设 2026/8/17 16:58:35

VibeCoding:AI如何实现“审美很绝”的自动拼图?

你有没有遇到过这样的场景:手机相册里攒了几十张、上百张旅行照片,想发个朋友圈,却不知道该怎么排版才好看?九宫格太单调,单张又觉得不够有故事感。或者,团队做了一次活动,拍了几百张现场照片&a…

作者头像 李华