android實現(xiàn)音樂跳動效果的示例代碼
效果圖
實現(xiàn)
整體的流程圖如下
上面主要步驟分為3個
1、計算寬度能放下多少列的音頻塊。
2、計算每一列中音頻塊的個數(shù)
3、繪制音頻塊
1、計算寬度能放下多少列的音頻塊。
設置音頻塊的寬度為danceWidth,音頻塊橫向之間的間距為danceGap,那么可以算出能放的列數(shù):
/** * 先計算當前寬度能夠放下多少個音頻塊 */ val widthNum = (getAvailableWith() / (danceGap + danceWidth)).toInt() /** * 獲取可以用的寬度 */ private fun getAvailableWith() = mCanvasWidth - paddingLeft - paddingRight
2、計算每一列中音頻塊的個數(shù)
在算出橫向能放置多少音頻塊后,遍歷橫,然后繪制列中的音頻塊,列中的音頻塊的個數(shù)跟音頻的高低相關,這里實現(xiàn)方式是通過Visualizer這個類然后獲取到mRawAudioBytes數(shù)組,
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數(shù)組的大小是128,數(shù)組的區(qū)間范圍[-128,127],計算列的時候這里做了兩個比較重要的操作,第一個是怎么把mRawAudioBytes數(shù)組的值與音頻的個數(shù)做映射,第二個是怎么取mRawAudioBytes數(shù)組的值。
/** * 先計算當前寬度能夠放下多少個音頻塊 */ 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,遍歷橫的時候對下標進行一個映射,保證獲得的值是均勻的,
/** 通過這個映射得到index */ val index = (mRawAudioBytes.size) * (i.toFloat() / widthNum)
第二個映射,是得到了代表音頻大小的mRawAudioBytes數(shù)組,現(xiàn)在要把這里面的值跟列的高度做一個映射,值越大高度越高,音頻塊就越多。
val num = (getAvailableHeight() / (danceHeight + danceGap)).toInt() val b = (mRawAudioBytes[index.toInt()] + 128).toFloat() / 255f var heightNum =(b * num).toInt()
上面是先得到列最多能展示多少音頻塊,再根據(jù)mRawAudioBytes的值來算出當前列展示多少個音頻塊。這一步也叫歸一化,區(qū)間映射。
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 }
就是根據(jù)高度來繪制rectangle,算出一列能繪制多少個音頻塊,每一個音頻塊是一個rectangle,然后繪制rectangle,為了效果更好,判斷上面的音頻塊加上漸變。
使用方法
<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" />
- shader_num 頂部加漸變的個數(shù)
- color_end 漸變尾部顏色
- color_start 漸變開頭顏色
- color_center 漸變中間顏色
- min_dance_num 每一列中最少顯示的個數(shù)
- max_dance_num 每一列中最大顯示的個數(shù)
- dance_gap 每一個音頻格之間的間距
到此這篇關于android實現(xiàn)音樂跳動效果的示例代碼的文章就介紹到這了,更多相關android 音樂跳動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android App中實現(xiàn)圖片異步加載的實例分享
這篇文章主要介紹了Android App中實現(xiàn)圖片異步加載的實例分享,這樣GridView在加載大量圖片時便可以延時分布顯示,需要的朋友可以參考下2016-04-04Android編程實現(xiàn)手繪及保存為圖片的方法(附demo源碼下載)
這篇文章主要介紹了Android編程實現(xiàn)手繪及保存為圖片的方法,涉及Android畫布的使用及圖片的操作技巧,并附帶了demo源碼供讀者下載,需要的朋友可以參考下2015-12-12Android源碼導入AndroidStudio或IntelliJ?IDEA的方法
這篇文章主要介紹了Android源碼導入AndroidStudio或IntelliJ?IDEA的方法,用idegen來生成針對AndroidStudio或IntelliJ?IDEA的Android系統(tǒng)源代碼工程配置文件,需要的朋友可以參考下2022-08-08