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

Compose RangeSlider数值舍入触发IllegalArgumentException崩溃求助

解决Jetpack Compose RangeSlider舍入导致的崩溃问题

这个崩溃是因为RangeSlider接收到了无效的数值范围(start > end),触发了coerceIn方法的参数校验失败。具体场景是当滑块范围极小(如8.99-8.99)时,拖动过程中Float的精度误差或舍入操作导致start和end顺序颠倒,最终传入了不合法的范围。

方案1:实时修正滑块范围合法性

在onValueChange中直接修正范围,确保始终满足start <= end,避免无效范围传入RangeSlider:

var sliderPosition by remember { 
    // 初始化时先校验初始范围合法性
    val initialRange = if (minSelected > maxSelected) maxSelected..minSelected else minSelected..maxSelected
    mutableStateOf(initialRange) 
}
RangeSlider(
    values = sliderPosition,
    onValueChange = { newRange ->
        // 强制保证start <= end,纠正可能的顺序颠倒
        val validRange = newRange.start.coerceAtMost(newRange.endInclusive)..newRange.start.coerceAtLeast(newRange.endInclusive)
        sliderPosition = validRange
    },
    valueRange = minPrice..maxPrice,
    onValueChangeFinished = {
        val roundedStart = sliderPosition.start.roundToTwoDecimal()
        val roundedEnd = sliderPosition.endInclusive.roundToTwoDecimal()
        // 再次校验舍入后的范围合法性
        val finalStart = min(roundedStart, roundedEnd)
        val finalEnd = max(roundedStart, roundedEnd)
        onPriceFilterRangeChanged(finalStart, finalEnd)
    }
)

方案2:优化舍入函数,降低Float精度误差

Float的精度限制会导致类似8.99的数值实际存储为8.989999...,优化舍入函数,借助Double的更高精度减少误差:

fun Float.roundToTwoDecimal(): Float {
    // 先转Double提升精度,再执行舍入操作
    return (this * 100).toDouble().roundToInt().toFloat() / 100.0f
}

额外建议

如果业务允许,建议使用Double类型存储价格数值。Float的精度问题在处理货币类场景中更容易引发异常,Double的精度能更好地适配两位小数的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:23:09