Ai
2 Star 1 Fork 1

Aivin_CodeShare/android_tool_code

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
AudioWaveView.java 7.49 KB
一键复制 编辑 原始数据 按行查看 历史
Aivin 提交于 2020-12-30 17:28 +08:00 . -
package com.wk.unittestshow;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver;
import androidx.annotation.NonNull;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* 声音波形的view <br>
* 波形能左右移动的原理: <br>
* 将自定义控件分成 listMaxSize 份,每份对应一个分贝值 ,
* 根据分贝值的大小 来决定 线条的高度。
* 分贝值更新引起ui更新,所以会形成从左向右效果。
* mRecDataList.add(dbValue) ;
* mRecDataList.remove(0) ;
*/
public class AudioWaveView extends View {
private Bitmap mBackgroundBitmap;
private Canvas mBackCanVans = new Canvas();
/**波浪的画笔*/
private Paint mPaint;
/**绘制最终画面的 画笔*/
private Paint mViewPaint;
private final ArrayList<Integer> mRecDataList = new ArrayList<>();
private int mScale = 1;
/**控件总长度*/
private int viewWidth;
/**高度中间线 ,作为基准线*/
private int mBaseLine;
/**波形之间线与线的间隔*/
private int smaleLineWidth = 0;
/**一共画多少个小线条*/
int listMaxSize = 0 ;
/**是否画出基线*/
private boolean mDrawBase = true;
private boolean mPause = false;
/**1 只画上面的波纹 ,2、上下都画*/
private int mWaveCount = 2;
private Context context ;
public AudioWaveView(Context context) {
super(context);
init(context, null);
}
public AudioWaveView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public AudioWaveView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mBackgroundBitmap != null && !mBackgroundBitmap.isRecycled()) {
mBackgroundBitmap.recycle();
}
}
public void init(Context context, AttributeSet attrs) {
// 防止因为xml可视化失败导致编译错误
if (isInEditMode()){
return;
}
this.context = context ;
mPaint = new Paint();
mPaint.setColor(Color.parseColor("#00ff33"));
mViewPaint = new Paint();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
creatBackGroundBitmap();
}
@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (visibility == VISIBLE && mBackgroundBitmap == null) {
creatBackGroundBitmap();
}
}
private void creatBackGroundBitmap() {
ViewTreeObserver vto = getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
if (getWidth() > 0 && getHeight() > 0) {
smaleLineWidth = WkDeviceInforTool.getPixByDp( context ,2) ;
listMaxSize = getWidth() / smaleLineWidth ;
viewWidth = getWidth();
mBaseLine = getHeight() / 2;
mBackgroundBitmap = Bitmap.createBitmap( getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mBackCanVans.setBitmap(mBackgroundBitmap);
mBackCanVans.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
ViewTreeObserver vto = getViewTreeObserver();
// 移除绘制回调函数
vto.removeOnPreDrawListener(this);
}
return true;
}
});
}
private void updateDrawParam(){
ArrayList<Integer> dataList = new ArrayList<>();
synchronized (mRecDataList) {
if (mRecDataList.size() != 0) {
try {
dataList = (ArrayList<Integer>) deepCopy(mRecDataList);
} catch (Exception e) {
e.printStackTrace();
}
}
}
if (!mPause) {
// 获得最新缩放参数
updateScale(dataList);
if (mBackCanVans != null) {
// 清除画布
mBackCanVans.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
// 绘制基准线
if (mDrawBase) {
mBackCanVans.drawLine(0, mBaseLine, viewWidth, mBaseLine, mPaint);
}
//绘制小线条形成波浪
int dbSize = dataList.size();
for (int i = 0, j = 0; i < dbSize; i++, j += smaleLineWidth) {
int dbValue = dataList.get(i);
drawDbLine(dbValue, j);
}
// 通知 重绘
postInvalidate();
}
}
}
@Override
protected void onDraw(Canvas c) {
super.onDraw(c);
if ( mBackgroundBitmap != null) {
c.drawBitmap(mBackgroundBitmap, 0, 0, mViewPaint);
}
}
/***
* 根据当前分贝值对应的一小段 线条
*/
private void drawDbLine(int dbValue, int smaleLineWidth) {
int max = mBaseLine - dbValue / mScale;
if (mWaveCount == 2) {
int min= mBaseLine + dbValue / mScale;
mBackCanVans.drawLine(smaleLineWidth, mBaseLine, smaleLineWidth, max, mPaint);
mBackCanVans.drawLine(smaleLineWidth, mBaseLine , smaleLineWidth,min , mPaint);
} else {
mBackCanVans.drawLine(smaleLineWidth, mBaseLine, smaleLineWidth, max, mPaint);
}
}
/**
* deepClone
* @param src list
* @return dest
*/
public List deepCopy(ArrayList src) throws IOException, ClassNotFoundException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(src);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
return (ArrayList) in.readObject();
}
/**
* 根据当前块数据 更新 缩放音频显示的比例
*/
private void updateScale(ArrayList<Integer> list) {
int allMax = 0;
for (int i = 0; i < list.size(); i++) {
int sh = list.get(i);
if ( sh > allMax) {
allMax = sh;
}
}
int curScale = allMax / mBaseLine;
if (curScale > mScale) {
mScale = curScale == 0 ? 1 : curScale ;
}
}
/**
* 停止绘制
*/
public void stopView( ) {
mRecDataList.clear();
mBackCanVans.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
}
public void updateDataList(int dbValue ){
if(mRecDataList.size() > listMaxSize){
mRecDataList.add(dbValue) ;
mRecDataList.remove(0) ;
}else{
mRecDataList.add(dbValue) ;
}
updateDrawParam();
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/Aivin_CodeShare/android_tool_code.git
git@gitee.com:Aivin_CodeShare/android_tool_code.git
Aivin_CodeShare
android_tool_code
android_tool_code
master

搜索帮助