文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

android实现音乐跳动效果的示例代码

2024-04-02 19:55

关注

效果图

实现

整体的流程图如下

上面主要步骤分为3个
1、计算宽度能放下多少列的音频块。
2、计算每一列中音频块的个数
3、绘制音频块

1、计算宽度能放下多少列的音频块。

设置音频块的宽度为danceWidth,音频块横向之间的间距为danceGap,那么可以算出能放的列数:



        val widthNum = (getAvailableWith() / (danceGap + danceWidth)).toInt()

  
    private fun getAvailableWith() = mCanvasWidth - paddingLeft - paddingRight

2、计算每一列中音频块的个数

在算出横向能放置多少音频块后,遍历横,然后绘制列中的音频块,列中的音频块的个数跟音频的高低相关,这里实现方式是通过Visualizer这个类然后获取到mRawAudioBytes数组,


 mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
            @Override
            public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
                                              int samplingRate) {
                BaseVisualizer.this.mRawAudioBytes = bytes;
                invalidate();
            }

            @Override
            public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
                                         int samplingRate) {
            }
        }, Visualizer.getMaxCaptureRate() / 2, true, false);

这里设置的获取的mRawAudioBytes数组的大小是128,数组的区间范围[-128,127],计算列的时候这里做了两个比较重要的操作,第一个是怎么把mRawAudioBytes数组的值与音频的个数做映射,第二个是怎么取mRawAudioBytes数组的值。


 
        val widthNum = (getAvailableWith() / (danceGap + danceWidth)).toInt()
        Log.d(
            TAG,
            "widthNum $widthNum"
        )
        

        
        var lastDanceRight = paddingLeft.toFloat()
        if (widthNum > 0 && mRawAudioBytes != null && mRawAudioBytes.isNotEmpty())
            for (i in 0 until widthNum) {
                //先算出当前高度,然后再算这个高度能放下多少个音频块
                val num = (getAvailableHeight() / (danceHeight + danceGap)).toInt()
                val index = (mRawAudioBytes.size) * (i.toFloat() / widthNum)
                val b = (mRawAudioBytes[index.toInt()] + 128).toFloat() / 255f
                var heightNum =
                    (b * num).toInt()
                if (heightNum < miniNum) {
                    heightNum = miniNum
                }
                if (heightNum > maxNum) {
                    heightNum = maxNum
                }
                //拿到最顶部的高度
                var lastHeight = mCanvasHeight - paddingStart.toFloat()
                Log.d(
                    TAG,
                    "heightNum $heightNum lastHeight $lastHeight lastDanceRight $lastDanceRight ${mRawAudioBytes[i]} $num $b $index"
                )
                lastHeight = drawItem(heightNum, lastDanceRight, lastHeight, canvas)
                lastDanceRight += danceWidth + danceGap
            }

上面做了两个映射,首先可能有0~n横,但是mRawAudioBytes大小是128,遍历横的时候对下标进行一个映射,保证获得的值是均匀的,



val index = (mRawAudioBytes.size) * (i.toFloat() / widthNum)

第二个映射,是得到了代表音频大小的mRawAudioBytes数组,现在要把这里面的值跟列的高度做一个映射,值越大高度越高,音频块就越多。


val num = (getAvailableHeight() / (danceHeight + danceGap)).toInt()
val b = (mRawAudioBytes[index.toInt()] + 128).toFloat() / 255f
var heightNum =(b * num).toInt()

上面是先得到列最多能展示多少音频块,再根据mRawAudioBytes的值来算出当前列展示多少个音频块。这一步也叫归一化,区间映射。

3、绘制每一个音频块


    private fun drawItem(
        heightNum: Int,
        lastDanceRight: Float,
        lastHeight: Float,
        canvas: Canvas?
    ): Float {
        var lastHeight1 = lastHeight
        for (j in 0 until heightNum) {
            mDanceRect.set(
                lastDanceRight,
                lastHeight1 - danceHeight,
                lastDanceRight + danceWidth,
                lastHeight1
            )
            mPaint.shader = null
            if (j >= heightNum - shaderNum) {
                val backGradient = LinearGradient(
                    lastDanceRight,
                    lastHeight1 - danceHeight,
                    lastDanceRight + danceWidth,
                    lastHeight1,
                    intArrayOf(colorStart, colorCenter, colorEnd),
                    null,
                    Shader.TileMode.CLAMP
                )
                mPaint.shader = backGradient
            }
            canvas?.drawRoundRect(mDanceRect, 8f, 8f, mPaint)
            lastHeight1 -= (danceHeight + danceGap)
        }
        return lastHeight1
    }

就是根据高度来绘制rectangle,算出一列能绘制多少个音频块,每一个音频块是一个rectangle,然后绘制rectangle,为了效果更好,判断上面的音频块加上渐变。

github地址

使用方法


<com.masoudss.lib.DanceView
              android:id="@+id/danceView"
              android:layout_width="320dp"
              android:layout_height="300dp"
              android:layout_gravity="center"
              app:color_center="@color/red"
              app:color_end="@color/white"
              app:color_start="@color/yellow"
              app:dance_color="@color/yellow"
              app:dance_corner_radius="2dp"
              app:dance_gap="2dp"
              app:max_dance_num="30"
              app:min_dance_num="2"
              app:shader_num="3" />

到此这篇关于android实现音乐跳动效果的示例代码的文章就介绍到这了,更多相关android 音乐跳动内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网! 

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯