自定义时间选择器对话框开发:如何获取高亮区域选中时间?
解决RecyclerView时间选择器获取选中时间的方案
核心思路
你的高亮区域(constrainBg)是固定布局位置的,只需找到每个RecyclerView中与高亮区域中心重合的item,就能拿到对应时间值。具体分三步实现:
步骤1:计算高亮区域的中心坐标
先获取高亮布局在屏幕中的垂直位置,算出中心点Y坐标,用于匹配RecyclerView的item位置:
// 初始化阶段调用 val highlightRect = Rect() constrainBg.getHitRect(highlightRect) // 高亮区域的中心Y坐标(基于屏幕坐标系) val highlightCenterY = (highlightRect.top + highlightRect.bottom) / 2
步骤2:给RecyclerView添加滚动监听,实时记录选中位置
给小时、分钟RecyclerView分别设置滚动监听,在滚动过程或停止时,计算处于高亮中心的item并记录其position:
// 全局变量,存储选中的小时/分钟位置 var selectedHourPos = 0 var selectedMinutePos = 0 // 小时RecyclerView的滚动监听 rvHours.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { super.onScrollStateChanged(recyclerView, newState) // 滚动停止后确认选中位置 if (newState == RecyclerView.SCROLL_STATE_IDLE) { updateSelectedPosition(recyclerView, ::selectedHourPos) } } override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) // 滚动过程中实时更新选中位置(可选,提升交互流畅度) updateSelectedPosition(recyclerView, ::selectedHourPos) } }) // 分钟RecyclerView的滚动监听(逻辑和小时一致,替换变量即可) rvMints.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { super.onScrollStateChanged(recyclerView, newState) if (newState == RecyclerView.SCROLL_STATE_IDLE) { updateSelectedPosition(recyclerView, ::selectedMinutePos) } } override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) updateSelectedPosition(recyclerView, ::selectedMinutePos) } }) // 通用方法:计算当前RecyclerView中处于高亮中心的item位置 private fun updateSelectedPosition(recyclerView: RecyclerView, positionSetter: (Int) -> Unit) { val layoutManager = recyclerView.layoutManager as LinearLayoutManager val rvRect = Rect() recyclerView.getHitRect(rvRect) // 计算高亮中心相对于RecyclerView内部的Y坐标 val relativeCenterY = highlightCenterY - rvRect.top // 遍历可见item,匹配高亮中心位置 for (i in 0 until layoutManager.childCount) { val child = layoutManager.getChildAt(i) ?: continue val childRect = Rect() child.getHitRect(childRect) if (relativeCenterY in childRect.top..childRect.bottom) { val pos = layoutManager.getPosition(child) positionSetter(pos) break } } }
步骤3:点击“下一步”时获取时间
直接从你的数据源列表中,根据记录的position取出对应时间值:
// 假设小时数据源为hourList: List<String>,分钟数据源为minuteList: List<String> btnNext.setOnClickListener { val selectedHour = hourList[selectedHourPos] val selectedMinute = minuteList[selectedMinutePos] // 这里处理选中的时间,比如保存或跳转逻辑 Log.d("SelectedTime", "$selectedHour:$selectedMinute") }
补充注意事项
- 初始化RecyclerView时,必须设置垂直方向的LinearLayoutManager,并滚动到默认选中位置:
rvHours.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false) rvMints.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false) // 滚动到初始选中位置(比如0点0分) rvHours.scrollToPosition(selectedHourPos) rvMints.scrollToPosition(selectedMinutePos)
- 若需要让选中item自动对齐高亮中心,可在滚动停止后调用
smoothScrollToPosition,优化交互体验。
内容的提问来源于stack exchange,提问作者Ayaz Muhammad
相关产品推荐
相关产品推荐

