Transsion Tecno设备Android Slider值越界崩溃问题求助
问题描述
使用Google Material组件的Slider实现数值设置功能,布局中已明确设置valueFrom="0"和valueTo="100",代码中也做了基本的非空和NaN判断,在数千台设备上运行正常,但在Transsion Tecno设备上出现崩溃,报错信息如下:
Fatal Exception: java.lang.IllegalStateException: Slider value(107.0) must be greater or equal to valueFrom(0.0), and lower or equal to valueTo(100.0)
at com.google.android.material.slider.BaseSlider.validateValues(BaseSlider.java:621)...
可能原因
推测是Transsion Tecno的定制系统对Material Slider的属性解析存在兼容性问题,导致布局中设置的范围约束未生效;或是设备触摸滑动时,系统传递给Slider的value超出了预期范围;也可能是ViewModel中的sliderProgress值出现异常。
解决方案
1. 强制限制Slider值的范围
在设置Slider值时,通过coerceIn方法将值强制约束在0-100范围内,从根源避免超出限制:
viewModel.sliderProgress.observe(viewLifecycleOwner) { progress -> val clampedValue = progress?.toFloat()?.coerceIn(0f, 100f) ?: 0f binding.sSlider.value = clampedValue }
2. 监听Slider变化时提前约束值
在Slider的addOnChangeListener中,先对传入的value做范围约束,再处理逻辑:
binding.sSlider.addOnChangeListener { _, value: Float, _ -> if (!value.isNaN()) { val clampedValue = value.coerceIn(0f, 100f).roundToInt() viewModel.setValueFromSlider(clampedValue) } }
3. 代码中显式设置Slider范围
避免布局属性在定制系统中未被正确解析,在初始化Slider时手动设置范围:
private fun initSlider() { binding.sSlider.apply { valueFrom = 0f valueTo = 100f } binding.sSlider.addOnChangeListener { _, value: Float, _ -> if (!value.isNaN()) { val clampedValue = value.coerceIn(0f, 100f).roundToInt() viewModel.setValueFromSlider(clampedValue) } } viewModel.sliderProgress.observe(viewLifecycleOwner) { progress -> val clampedValue = progress?.toFloat()?.coerceIn(0f, 100f) ?: 0f binding.sSlider.value = clampedValue } }
4. 添加异常捕获兜底
如果以上方案仍无法解决,在设置Slider值的代码块中添加try-catch,防止崩溃扩散:
viewModel.sliderProgress.observe(viewLifecycleOwner) { progress -> try { val clampedValue = progress?.toFloat()?.coerceIn(0f, 100f) ?: 0f binding.sSlider.value = clampedValue } catch (e: IllegalStateException) { // 可添加日志记录,便于后续排查 binding.sSlider.value = 0f } }
内容的提问来源于stack exchange,提问作者Tom11

