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

Android中如何让RangeSlider滑块顶部显示12小时制时间

实现RangeSlider滑块顶部显示12小时制时间

问题说明

已实现RangeSlider滑动时在日志输出12小时制时间区间,但需要在起始和结束滑块顶部显示对应的12小时制时间,而滑块默认仅支持显示float数值,需实现如下预期UI效果:
预期UI

现有代码

XML布局代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <com.google.android.material.slider.RangeSlider
        android:id="@+id/range_slider"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        app:thumbColor="@color/colorPrimary"
        app:thumbRadius="12dp"
        app:trackColorActive="@color/colorPrimary"
        app:trackHeight="4dp" />

</RelativeLayout>

Activity代码

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.rovedashcam.android.R
import kotlinx.android.synthetic.main.custom_date_picker_title.range_slider

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val startTime = 0f // 起始时间(午夜后的分钟数)
        val endTime = (24 * 60).toFloat()// 结束时间(午夜后的分钟数)
        val timeInterval = 15f // 时间间隔(分钟)

        range_slider.valueFrom = startTime
        range_slider.valueTo = endTime

        range_slider.stepSize = timeInterval
        range_slider.values = mutableListOf(startTime, endTime)

        // 处理滑块变化事件
        range_slider.addOnChangeListener { _, _, _ ->
            val startMinute = range_slider.values[0].toInt()
            val endMinute = range_slider.values[1].toInt()

            val startHour = startMinute / 60
            val startMinuteRemainder = startMinute % 60
            val endHour = endMinute / 60
            val endMinuteRemainder = endMinute % 60

            val startTimeStr = String.format(
                "%02d:%02d %s",
                if (startHour == 0 || startHour == 12) 12 else startHour % 12,
                startMinuteRemainder,
                if (startHour < 12) "AM" else "PM"
            )
            val endTimeStr = String.format(
                "%02d:%02d %s",
                if (endHour == 0 || endHour == 12) 12 else endHour % 12,
                endMinuteRemainder,
                if (endHour < 12) "AM" else "PM"
            )
            Log.d("Time Interval", "$startTimeStr--$endTimeStr");
        }
    }

}

解决方案

使用Material Components提供的RangeSlider.setLabelFormatter()方法,自定义标签显示格式,将float类型的分钟数转换为12小时制时间字符串。

修改后的完整Activity代码

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.rovedashcam.android.R
import kotlinx.android.synthetic.main.custom_date_picker_title.range_slider

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val startTime = 0f // 起始时间(午夜后的分钟数)
        val endTime = (24 * 60).toFloat()// 结束时间(午夜后的分钟数)
        val timeInterval = 15f // 时间间隔(分钟)

        range_slider.valueFrom = startTime
        range_slider.valueTo = endTime

        range_slider.stepSize = timeInterval
        range_slider.values = mutableListOf(startTime, endTime)

        // 自定义滑块顶部标签格式
        range_slider.setLabelFormatter { value ->
            val totalMinutes = value.toInt()
            val hour = totalMinutes / 60
            val minute = totalMinutes % 60
            // 转换为12小时制显示格式
            val displayHour = if (hour == 0 || hour == 12) 12 else hour % 12
            val period = if (hour < 12) "AM" else "PM"
            String.format("%02d:%02d %s", displayHour, minute, period)
        }

        // 处理滑块变化事件
        range_slider.addOnChangeListener { _, _, _ ->
            val startMinute = range_slider.values[0].toInt()
            val endMinute = range_slider.values[1].toInt()

            val startHour = startMinute / 60
            val startMinuteRemainder = startMinute % 60
            val endHour = endMinute / 60
            val endMinuteRemainder = endMinute % 60

            val startTimeStr = String.format(
                "%02d:%02d %s",
                if (startHour == 0 || startHour == 12) 12 else startHour % 12,
                startMinuteRemainder,
                if (startHour < 12) "AM" else "PM"
            )
            val endTimeStr = String.format(
                "%02d:%02d %s",
                if (endHour == 0 || endHour == 12) 12 else endHour % 12,
                endMinuteRemainder,
                if (endHour < 12) "AM" else "PM"
            )
            Log.d("Time Interval", "$startTimeStr--$endTimeStr");
        }
    }

}

额外注意事项

确保项目依赖的Material Components库版本足够新,避免方法不存在的问题,可在build.gradle中检查:

implementation 'com.google.android.material:material:1.9.0' // 或更高版本

原理说明

setLabelFormatter()接收LabelFormatter接口实现,其getFormattedValue()方法会传入当前滑块的float值,返回自定义的显示字符串,通过该方法可完全控制滑块顶部标签的内容,满足12小时制时间的显示需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:00:01