当前位置: 首页 > backend >正文

Android Compose 自定义滑动进度条

androidx.compose.material3 我用1.2.0版本的Slider非常好用,但是升级到1.3.2后滑轨后面多了个点,滑块背景也移除不掉而且默认透明了我暂时没有找到让他不透明。所以自定义了一个先用着。

@Composable
fun CustomSlider(state: CustomSliderState,modifier: Modifier = Modifier,trackHeight: Dp = 4.dp,thumbSize: Dp = 24.dp,trackColor: Color = Color.Gray,progressColor: Color = Color.Blue,thumbColor: Color = Color.White,onValueChange: ((Float) -> Unit)? = null,onValueChangeFinished: ((Float) -> Unit)? = null
) {var sliderWidth by remember { mutableFloatStateOf(0f) }Box(modifier = modifier.height(thumbSize + 16.dp) // 确保足够高度容纳滑块.pointerInput(Unit) {awaitEachGesture {val event = awaitPointerEvent(PointerEventPass.Initial)if (event.changes.firstOrNull()?.changedToDown() == true) {val down = awaitFirstDown(requireUnconsumed = true)state.setPressed(true)val newPosition = (event.changes.first().position.x / sliderWidth).coerceIn(0f, 1f)val newValue = state.range.start + newPosition * (state.range.endInclusive - state.range.start)state.updateValue(newValue)onValueChange?.invoke(state.value)var drag: PointerInputChange?do {drag = awaitTouchSlopOrCancellation(down.id) { change, _ ->if (change.positionChange() != Offset.Zero) change.consume()}} while (drag != null && !drag.isConsumed)if (drag != null) {val dragResult = drag(drag.id) {val newPosition = (it.position.x / sliderWidth).coerceIn(0f, 1f)val newValue = state.range.start + newPosition * (state.range.endInclusive - state.range.start)state.updateValue(newValue)onValueChange?.invoke(state.value)}// 确保完成回调被触发if (!dragResult || drag.isConsumed) {onValueChangeFinished?.invoke(state.value)}} else {onValueChangeFinished?.invoke(state.value)}}}},contentAlignment = Alignment.CenterStart) {// 绘制轨道(Track)Canvas(modifier = Modifier.fillMaxWidth().clip(CircleShape).height(trackHeight).align(Alignment.CenterStart).onSizeChanged { size ->sliderWidth = size.width.toFloat()}) {// 背景轨道drawRect(color = trackColor,size = Size(size.width.toFloat(), trackHeight.toPx()))// 进度轨道drawRect(color = progressColor,size = Size(width = (state.value - state.range.start) / (state.range.endInclusive - state.range.start) * size.width,height = trackHeight.toPx()))}// 滑块(Thumb)根据你自己需求替换Box(modifier = Modifier.offset {IntOffset(x = ((state.value - state.range.start) / (state.range.endInclusive - state.range.start) * sliderWidth - thumbSize.toPx()/2).toInt(),y = 0)}.shadow(4.dp, CircleShape).size(thumbSize).background(thumbColor, CircleShape))}
}class CustomSliderState(initialValue: Float,internal val range: ClosedFloatingPointRange<Float> = 0f..1f
) {private val _value = mutableFloatStateOf(initialValue.coerceIn(range))private val _isPressed = mutableStateOf(false) // 新增按下状态val value: Floatget() = _value.floatValueval isPressed: Boolean // 暴露给外部get() = _isPressed.valuefun updateValue(newValue: Float) {_value.floatValue = newValue.coerceIn(range)}fun setPressed(pressed: Boolean) { // 更新按下状态_isPressed.value = pressed}
}@Composable
fun rememberCustomSliderState(initialValue: Float = 0f,range: ClosedFloatingPointRange<Float> = 0f..1f
): CustomSliderState {return remember { CustomSliderState(initialValue, range) }
}

 使用

 val sliderState = rememberCustomSliderState(initialValue = 0.5f,range = 0f..100f)CustomSlider(state = sliderState,modifier = Modifier.fillMaxWidth().padding(horizontal = 36.dp),trackHeight = 12.dp,thumbSize = 24.dp,trackColor = Color.LightGray,progressColor = Color(0xFF6200EE),thumbColor = Color.White,onValueChange = {Log.e("onValueChange","float---$it")},onValueChangeFinished = {Log.e("onValueChangeFinished","float---$it")})

http://www.xdnf.cn/news/13665.html

相关文章:

  • RAGFlow迁移到GPU服务器(Docker容器元数据修复)
  • Springboot3+的id字符串转化问题
  • LaTeX常用数学公式语法
  • 香橙派3B学习笔记10:snap打包C/C++程序与动态链接库(.so)
  • 数组方法_join()+_concat()+_reverse()+ _indexOf()
  • MS5110模数转换器可pin to pin兼容ADS1110
  • 「AI产业」| 《2025中国低空经济商业洞察报告(商业无人机应用篇)》
  • 【mysql】联合索引和单列索引的区别
  • Ceph分布式存储方案
  • 比亚迪座舱接入通义大模型,未来将联合打造更多AI智能座舱场景
  • 【JUC面试篇】Java并发编程高频八股——线程与多线程
  • 各项目变更频繁时,如何保持整体稳定
  • Linux 内核学习(10) --- Linux sysfs 节点创建
  • Testbed问题记录
  • 【每日likou】704. 二分查找 27. 移除元素 977.有序数组的平方
  • Pandas:你的数据分析瑞士军刀![特殊字符]✨
  • DeepCritic: SFT+RL两阶段训练突破LLM自我监督!显著提升大模型的自我批判能力!!
  • 构建康养人才职业成长加速器 —— 智慧康养实训室虚拟仿真建设方案
  • 【笔记】NVIDIA AI Workbench 中安装 CUDA 12.9
  • 其他UML图示例,用到再学习
  • 心理学行业IP变现新趋势:创客匠人赋能个人品牌崛起
  • 去除百度AI图像中包含的水印内容
  • PocketSCP:蛋白质口袋动态时空拓扑可视化分析新方法
  • 华为云Flexus+DeepSeek征文|华为云一键部署高可用版 Dify LLM 应用开发平台实践详解
  • 训练过程中的 Loss ?
  • DeviceNet转Modbus RTU协议转换网关在石油开采行业的应用
  • 常见系统设计
  • 2024蓝桥杯C/C++ B组国赛
  • C primer plus (第六版)第七章 编程练习第4题,第5题
  • SecureRandom.getInstanceStrong() 与虚拟机的爱恨情仇