直播軟體開發,Android自定義簡單的音訊波譜view
直播軟體開發,Android自定義簡單的音訊波譜view
package com.ysalliance.qifan.util.myview.voiceview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.TextView; import androidx.annotation.Nullable; import com.didichuxing.doraemonkit.widget.tableview.utils.DensityUtils; import com.ysalliance.qifan.R; import java.util.ArrayList; import java.util.List; import java.util.Random; public class VoisePlayingIcon extends View { //畫筆 private Paint paint; //跳動指標的集合 private List<Pointer> pointers; //跳動指標的數量 private int pointerNum; //邏輯座標 原點 private float basePointX; private float basePointY; //指標間的間隙 預設5dp private float pointerPadding; //每個指標的寬度 預設3dp private float pointerWidth; //指標的顏色 private int pointerColor = Color.RED; //控制開始/停止 private boolean isPlaying = false; //子執行緒 private Thread myThread; //指標波動速率 private int pointerSpeed; public VoisePlayingIcon(Context context) { super(context); init(); } public VoisePlayingIcon(Context context, @Nullable AttributeSet attrs) { super(context, attrs); //取出自定義屬性 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.voisePlayingIconAttr); pointerColor = ta.getColor(R.styleable.voisePlayingIconAttr_pointer_color, Color.RED); pointerNum = ta.getInt(R.styleable.voisePlayingIconAttr_pointer_num, 4);//指標的數量,預設為4 pointerWidth = DensityUtils.dp2px(getContext(), ta.getFloat(R.styleable.voisePlayingIconAttr_pointer_width, 5f));//指標的寬度,預設5dp pointerSpeed = ta.getInt(R.styleable.voisePlayingIconAttr_pointer_speed, 40); init(); } public VoisePlayingIcon(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.voisePlayingIconAttr); pointerColor = ta.getColor(R.styleable.voisePlayingIconAttr_pointer_color, Color.RED); pointerNum = ta.getInt(R.styleable.voisePlayingIconAttr_pointer_num, 4); pointerWidth = DensityUtils.dp2px(getContext(), ta.getFloat(R.styleable.voisePlayingIconAttr_pointer_width, 5f)); pointerSpeed = ta.getInt(R.styleable.voisePlayingIconAttr_pointer_speed, 40); init(); } /** * 初始化畫筆與指標的集合 */ private void init() { paint = new Paint(); paint.setAntiAlias(true); paint.setColor(pointerColor); pointers = new ArrayList<>(); } /** * 在onLayout中做一些,寬高方面的初始化 * * @param changed * @param left * @param top * @param right * @param bottom */ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); //獲取邏輯原點的,也就是畫布左下角的座標。這裡減去了paddingBottom的距離 basePointY = getHeight() - getPaddingBottom(); Random random = new Random(); if (pointers != null) pointers.clear(); for (int i = 0; i < pointerNum; i++) { //建立指標物件,利用0~1的隨機數 乘以 可繪製區域的高度。作為每個指標的初始高度。 pointers.add(new Pointer((float) (0.1 * (random.nextInt(10) + 1) * (getHeight() - getPaddingBottom() - getPaddingTop())))); } //計算每個指標之間的間隔 總寬度 - 左右兩邊的padding - 所有指標佔去的寬度 然後再除以間隔的數量 pointerPadding = (getWidth() - getPaddingLeft() - getPaddingRight() - pointerWidth * pointerNum) / (pointerNum - 1); } /** * 開始繪畫 * * @param canvas */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //將x座標移動到邏輯原點,也就是左下角 basePointX = 0f + getPaddingLeft(); //迴圈繪製每一個指標。 for (int i = 0; i < pointers.size(); i++) { //繪製指標,也就是繪製矩形 canvas.drawRect(basePointX, basePointY - pointers.get(i).getHeight(), basePointX + pointerWidth, basePointY, paint); basePointX += (pointerPadding + pointerWidth); } } /** * 開始播放 */ public void start() { if (!isPlaying) { if (myThread == null) {//開啟子執行緒 myThread = new Thread(new MyRunnable()); myThread.start(); } isPlaying = true;//控制子執行緒中的迴圈 } } /** * 停止子執行緒,並重新整理畫布 */ public void stop() { isPlaying = false; invalidate(); } /** * 處理子執行緒發出來的指令,然後重新整理佈局 */ private Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); invalidate(); } }; /** * 子執行緒,迴圈改變每個指標的高度 */ public class MyRunnable implements Runnable { @Override public void run() { for (float i = 0; i < Integer.MAX_VALUE; ) {//建立一個死迴圈,每迴圈一次i+0.1 try { for (int j = 0; j < pointers.size(); j++) { //迴圈改變每個指標高度 float rate = (float) Math.abs(Math.sin(i + j));//利用正弦有規律的獲取0~1的數。 try { pointers.get(j).setHeight((basePointY - getPaddingTop()) * rate); //rate 乘以 可繪製高度,來改變每個指標的高度 }catch (Exception e){ Log.e("VoisePlayingIcon", "run: pointers.get(j).setHeight出錯:"+e.getMessage().toString()); } } Thread.sleep(pointerSpeed);//休眠一下下,可自行調節 if (isPlaying) { //控制開始/暫停 myHandler.sendEmptyMessage(0); i += 0.1; } } catch (InterruptedException e) { e.printStackTrace(); } } } } /** * 指標物件 */ public class Pointer { private float height; public Pointer(float height) { this.height = height; } public float getHeight() { return height; } public void setHeight(float height) { this.height = height; } } }
以上就是直播軟體開發,Android自定義簡單的音訊波譜view, 更多內容歡迎關注之後的文章
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2903340/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Android 入門(三)簡單自定義 ViewAndroidView
- Android開發之自定義View(一)AndroidView
- Android開發之自定義View(二)AndroidView
- 直播軟體開發,工具類的自定義彈窗效果
- android短視訊開發,自定義下拉選單Android
- Android自定義View之實現簡單炫酷的球體進度球AndroidView
- android canvas\paint\path簡單使用(自定義view必學)AndroidCanvasAIView
- Android自定義View–仿QQ音樂歌詞AndroidView
- Android自定義View:View(二)AndroidView
- 直播平臺軟體開發,實現自定義標題欄
- 簡單介紹Android自定義View實現時鐘功能AndroidView
- Android 自定義viewAndroidView
- Android: 自定義ViewAndroidView
- android簡單的自定義動畫Android動畫
- Android開發自定義View之滑動按鈕與自定義屬性AndroidView
- Android自定義View--仿QQ音樂歌詞AndroidView
- [Android]多層波紋擴散動畫——自定義View繪製Android動畫View
- Android開發進階——自定義View的使用及其原理探索AndroidView
- 直播平臺軟體開發,一個簡單的Android登入實現demoAndroid
- Android自定義View整合AndroidView
- Android自定義view-自繪ViewAndroidView
- 直播平臺軟體開發,簡單易修改的彈框元件元件
- flutter-簡單實現找妹子自定義viewFlutterView
- iOS開發簡單的音訊播放器iOS音訊播放器
- android自定義view(自定義數字鍵盤)AndroidView
- android自定義View&自定義ViewGroup(下)AndroidView
- android自定義View&自定義ViewGroup(上)AndroidView
- 重拾Android自定義ViewAndroidView
- Android自定義view詳解AndroidView
- Android 自定義 view 詳解AndroidView
- Android 控制元件框架、View的分發機制和自定義ViewAndroid控制元件框架View
- Android 自定義View:處理事件分發(四)AndroidView事件
- 直播軟體開發,自定義搜尋欄的圖示樣式和搜尋框
- Android自定義View之Canvas的使用AndroidViewCanvas
- Android 自定義View:手把手教你做一款簡單、好用的SuperEditTextAndroidView
- Android自定義View:MeasureSpec的真正意義與View大小控制AndroidView
- 直播系統程式碼,Android自定義View實現呼吸燈效果AndroidView
- 直播平臺原始碼,Android自定義View實現呼吸燈效果原始碼AndroidView