編輯:關於Android編程
音頻條形圖
如下圖所示就是這次的音頻條形圖:
由於只是自定義View的用法,我們就不去真實地監聽音頻輸入了,隨機模擬一些數字即可。
如果要實現一個如上圖的靜態音頻條形圖,相信大家應該可以很快找到思路,也就是繪制一個個的矩形,每個矩形之間稍微偏移一點距離即可。如下代碼就展示了一種計算坐標的方法。
for (int i = 0; i < mRectCount; i++) { // 矩形的繪制是從左邊開始到上、右、下邊(左右邊距離左邊畫布邊界的距離,上下邊距離上邊畫布邊界的距離) canvas.drawRect( (float) (mRectWidth * i + offset), currentHeight, (float) ( mRectWidth * (i + 1)), mRectHeight, mRectPaint ); }
如上代碼中,我們通過循環創建這些小的矩形,其中currentHeight就是每個小矩形的高,通過橫坐標的不斷偏移,就繪制出了這些靜態的小矩形。下面再通過矩形的高度隨機變化模擬音頻,這裡直接利用Math.randoom()方法來隨機改變這些高度,並賦值給currentHeight,代碼如下所示。
// 由於只是簡單的案例就不監聽音頻輸入,隨機模擬一些數字即可 mRandom = Math.random(); currentHeight = (float) (mRectHeight * mRandom);
這樣就能實現靜態效果了,但是如何實現動態效果呢?其實也是非常簡單的,只要在onDraw()方法中再去調用invalidate()方法通知View進行重繪就可以了。不過這裡不需要每次一繪制完新的矩形就通知View進行重繪,這樣會因為刷新速度太快反而影響效果。因此,我們可以使用如下代碼來進行View的延遲重繪,代碼如下:
posInvalidateDelayed(300);
這樣每隔300ms通知View進行重繪,就可以得到一個比較好的視覺效果了。最後添加一個漸變效果可以使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(); // 獲取單個矩形的寬度(減去的部分為到右邊界的間距) mRectWidth = (mWidth-offset) / mRectCount; // 實例化一個線性漸變 mLinearGradient = new LinearGradient( 0, 0, mRectWidth, mRectHeight, topColor, downColor, Shader.TileMode.CLAMP ); // 添加進畫筆的著色器 mRectPaint.setShader(mLinearGradient); }
從這個例子中,我們可以知道,在創建自定義View的時候,需要一步一步來,從一個基本的效果開始,慢慢地添加功能,繪制更復雜的效果。不論是多麼復雜的自定義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 { // 音頻矩形的數量 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){ // 將屬性存儲到TypedArray中 TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.MyAF); mRectPaint = new Paint(); // 添加矩形畫筆的基礎顏色 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)); // 設置矩形的數量 mRectCount=ta.getInt(R.styleable.MyAF_AFCount, 10); // 設置重繪的時間間隔,也就是變化速度 mSpeed=ta.getInt(R.styleable.MyAF_AFSpeed, 300); // 每個矩形的間隔 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(); // 獲取單個矩形的寬度(減去的部分為到右邊界的間距) mRectWidth = (mWidth-offset) / mRectCount; // 實例化一個線性漸變 mLinearGradient = new LinearGradient( 0, 0, mRectWidth, mRectHeight, topColor, downColor, Shader.TileMode.CLAMP ); // 添加進畫筆的著色器 mRectPaint.setShader(mLinearGradient); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); double mRandom; float currentHeight; for (int i = 0; i < mRectCount; i++) { // 由於只是簡單的案例就不監聽音頻輸入,隨機模擬一些數字即可 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實現音頻條形圖效果(仿音頻動畫無監聽音頻輸入),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對本站網站的支持!
onReceiveError是WebViewClient提供的方法,用於網頁產生錯誤時進行回調處理。1. 舊版的onReceiveError在API23之前,該方法的簽名
Lumia手機看電子書的限制頗多,比如直接將電子書復制到手機Document文件夾不能被閱讀軟件識別,用Office看書的體驗遠遜於專業的閱讀軟件。那麼,L
前兩天在開發在微信訪問的HTML5頁面,裡面有個訂單查詢要選擇時間,剛開始使用的<input type="date">輸入框,沒加任何的樣
AudioPolicyService是策略的制定者,比如什麼時候打開音頻接口設備、某種Stream類型的音頻對應什麼設備等等。而AudioFlinger則是策略的執行者,