You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义时间选择器对话框开发:如何获取高亮区域选中时间?

解决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")
}

补充注意事项

  1. 初始化RecyclerView时,必须设置垂直方向的LinearLayoutManager,并滚动到默认选中位置:
rvHours.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
rvMints.layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
// 滚动到初始选中位置(比如0点0分)
rvHours.scrollToPosition(selectedHourPos)
rvMints.scrollToPosition(selectedMinutePos)
  1. 若需要让选中item自动对齐高亮中心,可在滚动停止后调用smoothScrollToPosition,优化交互体验。

内容的提问来源于stack exchange,提问作者Ayaz Muhammad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:47:26