Android實(shí)現(xiàn)音頻條形圖效果(仿音頻動(dòng)畫無監(jiān)聽音頻輸入)
音頻條形圖
如下圖所示就是這次的音頻條形圖:
由于只是自定義View的用法,我們就不去真實(shí)地監(jiān)聽音頻輸入了,隨機(jī)模擬一些數(shù)字即可。
如果要實(shí)現(xiàn)一個(gè)如上圖的靜態(tài)音頻條形圖,相信大家應(yīng)該可以很快找到思路,也就是繪制一個(gè)個(gè)的矩形,每個(gè)矩形之間稍微偏移一點(diǎn)距離即可。如下代碼就展示了一種計(jì)算坐標(biāo)的方法。
for (int i = 0; i < mRectCount; i++) { // 矩形的繪制是從左邊開始到上、右、下邊(左右邊距離左邊畫布邊界的距離,上下邊距離上邊畫布邊界的距離) canvas.drawRect( (float) (mRectWidth * i + offset), currentHeight, (float) ( mRectWidth * (i + 1)), mRectHeight, mRectPaint ); }
如上代碼中,我們通過循環(huán)創(chuàng)建這些小的矩形,其中currentHeight就是每個(gè)小矩形的高,通過橫坐標(biāo)的不斷偏移,就繪制出了這些靜態(tài)的小矩形。下面再通過矩形的高度隨機(jī)變化模擬音頻,這里直接利用Math.randoom()方法來隨機(jī)改變這些高度,并賦值給currentHeight,代碼如下所示。
// 由于只是簡單的案例就不監(jiān)聽音頻輸入,隨機(jī)模擬一些數(shù)字即可 mRandom = Math.random(); currentHeight = (float) (mRectHeight * mRandom);
這樣就能實(shí)現(xiàn)靜態(tài)效果了,但是如何實(shí)現(xiàn)動(dòng)態(tài)效果呢?其實(shí)也是非常簡單的,只要在onDraw()方法中再去調(diào)用invalidate()方法通知View進(jìn)行重繪就可以了。不過這里不需要每次一繪制完新的矩形就通知View進(jìn)行重繪,這樣會(huì)因?yàn)樗⑿滤俣忍旆炊绊懶Ч?。因此,我們可以使用如下代碼來進(jìn)行View的延遲重繪,代碼如下:
posInvalidateDelayed(300);
這樣每隔300ms通知View進(jìn)行重繪,就可以得到一個(gè)比較好的視覺效果了。最后添加一個(gè)漸變效果可以使View更加逼真,代碼如下所示:
@Override protected void onSizeChanged(int w,int h,int oldW,int oldH) { super.onSizeChanged(w, h, oldW, oldH); // 漸變效果 LinearGradient mLinearGradient; // 畫布的寬 int mWidth; // 獲取畫布的寬 mWidth = getWidth(); // 獲取矩形的最大高度 mRectHeight = getHeight(); // 獲取單個(gè)矩形的寬度(減去的部分為到右邊界的間距) mRectWidth = (mWidth-offset) / mRectCount; // 實(shí)例化一個(gè)線性漸變 mLinearGradient = new LinearGradient( 0, 0, mRectWidth, mRectHeight, topColor, downColor, Shader.TileMode.CLAMP ); // 添加進(jìn)畫筆的著色器 mRectPaint.setShader(mLinearGradient); }
從這個(gè)例子中,我們可以知道,在創(chuàng)建自定義View的時(shí)候,需要一步一步來,從一個(gè)基本的效果開始,慢慢地添加功能,繪制更復(fù)雜的效果。不論是多么復(fù)雜的自定義View都一定是慢慢迭代起來的功能,所以不要覺得自定義View有多難。千里之行始于足下,只要開始做,慢慢地就能越來越熟練。
代碼
以下是這次的完整代碼:
package com.example.customaf; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Shader; import android.support.v4.content.ContextCompat; import android.util.AttributeSet; import android.view.View; import com.example.afanalog.R; /** * 自定義的音頻模擬條形圖 * Created by shize on 2016/9/5. */ public class MyAF extends View { // 音頻矩形的數(shù)量 private int mRectCount; // 音頻矩形的畫筆 private Paint mRectPaint; // 漸變顏色的兩種 private int topColor, downColor; // 音頻矩形的寬和高 private int mRectWidth, mRectHeight; // 偏移量 private int offset; // 頻率速度 private int mSpeed; public MyAF(Context context) { super(context); } public MyAF(Context context, AttributeSet attrs) { super(context, attrs); setPaint(context, attrs); } public MyAF(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setPaint(context, attrs); } public void setPaint(Context context, AttributeSet attrs){ // 將屬性存儲(chǔ)到TypedArray中 TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyAF); mRectPaint = new Paint(); // 添加矩形畫筆的基礎(chǔ)顏色 mRectPaint.setColor(ta.getColor(R.styleable.MyAF_AFTopColor, ContextCompat.getColor(context, R.color.top_color))); // 添加矩形漸變色的上面部分 topColor=ta.getColor(R.styleable.MyAF_AFTopColor, ContextCompat.getColor(context, R.color.top_color)); // 添加矩形漸變色的下面部分 downColor=ta.getColor(R.styleable.MyAF_AFDownColor, ContextCompat.getColor(context, R.color.down_color)); // 設(shè)置矩形的數(shù)量 mRectCount=ta.getInt(R.styleable.MyAF_AFCount, 10); // 設(shè)置重繪的時(shí)間間隔,也就是變化速度 mSpeed=ta.getInt(R.styleable.MyAF_AFSpeed, 300); // 每個(gè)矩形的間隔 offset=ta.getInt(R.styleable.MyAF_AFOffset, 5); // 回收TypeArray ta.recycle(); } @Override protected void onSizeChanged(int w,int h,int oldW,int oldH) { super.onSizeChanged(w, h, oldW, oldH); // 漸變效果 LinearGradient mLinearGradient; // 畫布的寬 int mWidth; // 獲取畫布的寬 mWidth = getWidth(); // 獲取矩形的最大高度 mRectHeight = getHeight(); // 獲取單個(gè)矩形的寬度(減去的部分為到右邊界的間距) mRectWidth = (mWidth-offset) / mRectCount; // 實(shí)例化一個(gè)線性漸變 mLinearGradient = new LinearGradient( 0, 0, mRectWidth, mRectHeight, topColor, downColor, Shader.TileMode.CLAMP ); // 添加進(jìn)畫筆的著色器 mRectPaint.setShader(mLinearGradient); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); double mRandom; float currentHeight; for (int i = 0; i < mRectCount; i++) { // 由于只是簡單的案例就不監(jiān)聽音頻輸入,隨機(jī)模擬一些數(shù)字即可 mRandom = Math.random(); currentHeight = (float) (mRectHeight * mRandom); // 矩形的繪制是從左邊開始到上、右、下邊(左右邊距離左邊畫布邊界的距離,上下邊距離上邊畫布邊界的距離) canvas.drawRect( (float) (mRectWidth * i + offset), currentHeight, (float) ( mRectWidth * (i + 1)), mRectHeight, mRectPaint ); } // 使得view延遲重繪 postInvalidateDelayed(mSpeed); } }
布局文件的完整代碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:custom="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.afanalog.MainActivity"> <com.example.customaf.MyAF android:layout_width="match_parent" android:layout_height="match_parent" custom:AFCount="15" custom:AFDownColor="@color/down_color" custom:AFSpeed="300" custom:AFTopColor="@color/top_color" custom:AFOffset="15" /> </LinearLayout>
以上所述是小編給大家介紹的Android實(shí)現(xiàn)音頻條形圖效果(仿音頻動(dòng)畫無監(jiān)聽音頻輸入),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
RecyclerView實(shí)現(xiàn)縱向和橫向滾動(dòng)
這篇文章主要為大家詳細(xì)介紹了RecyclerView實(shí)現(xiàn)縱向和橫向滾動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01Android開發(fā)之項(xiàng)目模塊化實(shí)踐教程
這篇文章主要給大家介紹了關(guān)于Android開發(fā)之項(xiàng)目模塊化的相關(guān)資料,文中通過示例代碼給各位Android開發(fā)者們介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)下吧。2017-09-09Android監(jiān)聽系統(tǒng)來電并彈出提示窗口
本篇文章主要介紹了Android監(jiān)聽系統(tǒng)來電并彈出提示窗口,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10Android自定義View實(shí)現(xiàn)柱狀波形圖的繪制
柱狀波形圖是一種常見的圖形。一個(gè)個(gè)柱子按順序排列,構(gòu)成一個(gè)波形圖。本文將利用Android自定義View實(shí)現(xiàn)柱狀波形圖的繪制,需要的可以參考一下2022-08-08Android-Jetpack-Navigation組件使用示例
這篇文章主要介紹了Android-Jetpack-Navigation組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08Android入門之使用RecyclerView完美實(shí)現(xiàn)瀑布流界面詳解
網(wǎng)上充滿著不完善的基于RecyclerView的瀑布流實(shí)現(xiàn),要么根本是錯(cuò)的、要么就是只知其一不知其二。本文就來用RecyclerView完美實(shí)現(xiàn)瀑布流界面,希望大家有所幫助2023-02-02Flutter實(shí)現(xiàn)簡單的內(nèi)容高亮效果
內(nèi)容高亮并不陌生,特別是在搜索內(nèi)容頁面,可以說四處可見,這篇文章主要為大家介紹了如何使用Flutter實(shí)現(xiàn)簡單的內(nèi)容高亮效果,需要的可以參考下2023-08-08如何在原有Android項(xiàng)目中快速集成React Native詳解
創(chuàng)建一個(gè)React Native項(xiàng)目并寫一個(gè)純的 React Native 應(yīng)用可以參考官方指南。下面這篇文章主要給大家介紹了關(guān)于如何在原有Android項(xiàng)目中快速集成React Native的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-12-12解決Android SurfaceView繪制觸摸軌跡閃爍問題的方法
這篇文章主要為大家詳細(xì)介紹了解決Android SurfaceView繪制觸摸軌跡閃爍問題的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03