仿微信语音 WaveView -- Compose 实现

之前写过一篇 仿微信语音 WaveView 实现 是用传统的自定义 View 方式实现的。这次是基于之前的动画逻辑,实现了 compose 版本的 SoundView。 整体的效果和传统 View 实现是一致的。

不过也是第一次使用 Compose,虽然有 AI 帮忙,但是要真正理解也学了好几天,整体的编码范式和 View 相差很大。一些 side effect 更加是不能用传统的 java 思维去理解😭,不然要狠狠踩坑了。

效果

缓动效果

正常收音效果

gif 图帧数低,可以直接看这个视频:www.bilibili.com/video/BV1Ar...

代码仓库

github.com/ultimateHan...

如何使用

目前已经发布到 maven central: repo1.maven.org/maven2/io/g...

  • 引入依赖: io.github.ultimatehandsomeboy666:soundwavelib-compose:1.0.1

  • 调用 SoundView() 这个 Composable 方法

kotlin 复制代码
@Composable
fun SoundWave(
    volume: Int,
    modifier: Modifier = Modifier,
    config: SoundWaveConfig = SoundWaveConfig()
) 

// 调用
SoundWave(
    volume = volume,
    modifier = Modifier.wrapContentSize(),
    config = SoundWaveConfig(
        volumeCount = 37,
        volumeIdleCount = 12,
        volumeBarColor = Color.Black.copy(alpha = 0.625f),
        maxVolumeBarHeight = 45.dp,
        minVolumeBarHeight = 4.dp,
        volumeBarHalfWidth = 0.9.dp,
        volumeBarMargin = 0.8.dp,
        idleHeightGetter = { x ->
            (x + 6).dp
        }
    )
)
  • 所有的配置都在 SoundVaveConfig 里设置,和 View 实现的参数配置一致。如下。
kotlin 复制代码
/**
 * 音波配置数据类
 * @param volumeCount 音柱总数量
 * @param volumeIdleCount 缓动状态下的音柱数量
 * @param maxVolume 最大音量值
 * @param minVolume 最小音量值
 * @param danceDuration 跳跃动画持续时间(毫秒)
 * @param maxDanceDelay 最大跳跃延迟时间(毫秒),代表了每个音柱间跳跃的相位差,如果为0则所有音柱同时整齐跳跃
 * @param idleDuration 一次完整缓动循环持续时间(毫秒)
 * @param maxIdleHeight 最大缓动高度
 * @param minVolumeBarHeight 音柱最小高度
 * @param maxVolumeBarHeight 音柱最大高度
 * @param volumeBarMargin 音柱间距
 * @param volumeBarHalfWidth 音柱半宽
 * @param volumeBarColor 音柱颜色
 * @param enableIdle 是否启用缓动状态
 * @param idleHeightGetter 缓动高度计算函数,输入索引返回对应高度
 * @param interpolator 插值器,用于控制单根音柱跳跃动画
 * @param volumeHeightDistribution 音柱高度分布,在音柱原有跳跃高度上乘以一个系数,达到不同区间音柱高度不同的效果
 */
data class SoundWaveConfig(
    val volumeCount: Int = 37,
    val volumeIdleCount: Int = 16,
    val minVolume: Int = 7,
    val maxVolume: Int = 45,
    val danceDuration: Long = 250L,
    val maxDanceDelay: Long = 80L,
    val idleDuration: Long = 3500L,
    val maxIdleHeight: Dp = 16.dp,
    val minVolumeBarHeight: Dp = 4.dp,
    val maxVolumeBarHeight: Dp = 36.dp,
    val volumeBarMargin: Dp = 3.dp,
    val volumeBarHalfWidth: Dp = 1.5.dp,
    val volumeBarColor: Color = Color(0XFF11192D),
    val enableIdle: Boolean = true,
    val idleHeightGetter: (Int) -> Dp = { x -> (x + 4).dp },
    val interpolator: Interpolator = VolumeDanceInterpolator(),
    val volumeHeightDistribution: FloatArray = floatArray(...)
)

总结

和 View 版本的逻辑一致,代码也不复杂。个人感觉效果确实挺不错的。如果有更多自定义需求,也可以把代码 copy 到项目里自己修改。

相关推荐
李斯维6 分钟前
布局性能优化利器:ViewStub 极简指南
android·性能优化
鹏北海11 分钟前
多标签页登录状态同步:一个简单而有效的解决方案
前端·面试·架构
_AaronWong16 分钟前
基于 Vue 3 的屏幕音频捕获实现:从原理到实践
前端·vue.js·音视频开发
孟祥_成都24 分钟前
深入 Nestjs 底层概念(1):依赖注入和面向切面编程 AOP
前端·node.js·nestjs
let_code25 分钟前
CopilotKit-丝滑连接agent和应用-理论篇
前端·agent·ai编程
Apifox1 小时前
Apifox 11 月更新|AI 生成测试用例能力持续升级、JSON Body 自动补全、支持为响应组件添加描述和 Header
前端·后端·测试
木易士心1 小时前
深入剖析:按下 F5 后,浏览器前端究竟发生了什么?
前端·javascript
在掘金801101 小时前
vue3中使用medium-zoom
前端·vue.js
xump1 小时前
如何在DevTools选中调试一个实时交互才能显示的元素样式
前端·javascript·css
折翅嘀皇虫1 小时前
fastdds.type_propagation 详解
java·服务器·前端