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
相关产品推荐
相关产品推荐

