本文简单记录由View绘制转为SurfaceView绘制的波形图问题.

上代码:

 public class VoiceLineView extends View {
private final int LINE = 0;
private final int RECT = 1; private int middleLineColor = Color.BLACK;
private int voiceLineColor = Color.BLACK;
private float middleLineHeight = 4;
private Paint paint;
private Paint paintVoicLine; /**
* 灵敏度
*/
private int sensibility = 4; private float maxVolume = 100; private float translateX = 0;
private boolean isSet = false; /**
* 振幅
*/
private float amplitude = 1;
/**
* 音量
*/
private float volume = 10;
private int fineness = 1;
private float targetVolume = 1; private long speedY = 50;
private float rectWidth = 25;
private float rectSpace = 5;
private float rectInitHeight = 4;
private List<Rect> rectList; private long lastTime = 0;
private int lineSpeed = 90; List<Path> paths = null; public VoiceLineView(Context context) {
super(context);
} public VoiceLineView(Context context, AttributeSet attrs) {
super(context, attrs);
initAtts(context, attrs);
} public VoiceLineView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAtts(context, attrs);
} private void initAtts(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.voiceView);
mode = typedArray.getInt(R.styleable.voiceView_viewMode, 0);
voiceLineColor = typedArray.getColor(R.styleable.voiceView_voiceLine, Color.BLACK);
maxVolume = typedArray.getFloat(R.styleable.voiceView_maxVolume, 100);
sensibility = typedArray.getInt(R.styleable.voiceView_sensibility, 4);
if (mode == RECT) {
rectWidth = typedArray.getDimension(R.styleable.voiceView_rectWidth, 25);
rectSpace = typedArray.getDimension(R.styleable.voiceView_rectSpace, 5);
rectInitHeight = typedArray.getDimension(R.styleable.voiceView_rectInitHeight, 4);
} else {
middleLineColor = typedArray.getColor(R.styleable.voiceView_middleLine, Color.BLACK);
middleLineHeight = typedArray.getDimension(R.styleable.voiceView_middleLineHeight, 4);
lineSpeed = typedArray.getInt(R.styleable.voiceView_lineSpeed, 90);
fineness = typedArray.getInt(R.styleable.voiceView_fineness, 1);
paths = new ArrayList<>(20);
for (int i = 0; i < 20; i++) {
paths.add(new Path());
}
}
typedArray.recycle();
} @Override
protected void onDraw(Canvas canvas) { drawMiddleLine(canvas);
drawVoiceLine(canvas);     run();
} private void drawMiddleLine(Canvas canvas) {
if (paint == null) {
paint = new Paint();
paint.setColor(middleLineColor);
paint.setAntiAlias(true);
}
canvas.save();
canvas.drawRect(0, getHeight() / 2 - middleLineHeight / 2, getWidth(), getHeight() / 2 + middleLineHeight / 2, paint);
canvas.restore();
} private void drawVoiceLine(Canvas canvas) {
lineChange();
if (paintVoicLine == null) {
paintVoicLine = new Paint();
paintVoicLine.setColor(voiceLineColor);
paintVoicLine.setAntiAlias(true);
paintVoicLine.setStyle(Paint.Style.STROKE);
paintVoicLine.setStrokeWidth(2);
}
canvas.save();
int moveY = getHeight() / 2;
for (int i = 0; i < paths.size(); i++) {
paths.get(i).reset();
paths.get(i).moveTo(getWidth(), getHeight() / 2);
}
for (float i = getWidth() - 1; i >= 0; i -= fineness) {
amplitude = 4 * volume * i / getWidth() - 4 * volume * i * i / getWidth() / getWidth();
for (int n = 1; n <= paths.size(); n++) {
float sin = amplitude * (float) Math.sin((i - Math.pow(1.22, n)) * Math.PI / 180 - translateX);
paths.get(n - 1).lineTo(i, (2 * n * sin / paths.size() - 15 * sin / paths.size() + moveY));
}
}
for (int n = 0; n < paths.size(); n++) {
if (n == paths.size() - 1) {
paintVoicLine.setAlpha(255);
} else {
paintVoicLine.setAlpha(n * 130 / paths.size());
}
if (paintVoicLine.getAlpha() > 0) {
canvas.drawPath(paths.get(n), paintVoicLine);
}
}
canvas.restore();
} public void setVolume(int volume) {
if (volume > maxVolume * sensibility / 25) {
isSet = true;
this.targetVolume = getHeight() * volume / 2 / maxVolume;
}
} private void lineChange() {
if (lastTime == 0) {
lastTime = System.currentTimeMillis();
translateX += 1.5;
} else {
if (System.currentTimeMillis() - lastTime > lineSpeed) {
lastTime = System.currentTimeMillis();
translateX += 1.5;
} else {
return;
}
}
if (volume < targetVolume && isSet) {
volume += getHeight() / 30;
} else {
isSet = false;
if (volume <= 10) {
volume = 10;
} else {
if (volume < getHeight() / 30) {
volume -= getHeight() / 60;
} else {
volume -= getHeight() / 30;
}
}
}
} public void run() { invalidate(); } }

上面是View的canvas实现的波形图绘制,cpu占用率比较高,在20%左右,一边录音一边绘制,手机发烫是最明显的感觉了.

下面我们换成SurfaceView绘制的

public class VoiceLineSurfaceView extends SurfaceView implements Runnable,SurfaceView.Callback {
private final int LINE = 0;
private final int RECT = 1; private int middleLineColor = Color.BLACK;
private int voiceLineColor = Color.BLACK;
private float middleLineHeight = 4;
private Paint paint;
private Paint paintVoicLine;/**
* 灵敏度
*/
private int sensibility = 4; private float maxVolume = 100; private float translateX = 0;
private boolean isSet = false; /**
* 振幅
*/
private float amplitude = 1;
/**
* 音量
*/
private float volume = 10;
private int fineness = 1;
private float targetVolume = 1; private long speedY = 50;
private float rectWidth = 25;
private float rectSpace = 5;
private float rectInitHeight = 4;
private List<Rect> rectList; private long lastTime = 0;
private int lineSpeed = 90;
   private SurfaceHolder surfaceHolder;
List<Path> paths = null;
private boolean isWaveDrawing = false;
private boolean isMiddleLineDrawing = true;
private Thread thread;
private Canvas canvas; public VoiceLineSurfaceView(Context context) {
super(context);
} public VoiceLineSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initAtts(context, attrs);
} public VoiceLineSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAtts(context, attrs);
} private void initAtts(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.voiceView);
mode = typedArray.getInt(R.styleable.voiceView_viewMode, 0);
voiceLineColor = typedArray.getColor(R.styleable.voiceView_voiceLine, Color.BLACK);
maxVolume = typedArray.getFloat(R.styleable.voiceView_maxVolume, 100);
sensibility = typedArray.getInt(R.styleable.voiceView_sensibility, 4);
middleLineColor = typedArray.getColor(R.styleable.voiceView_middleLine, Color.BLACK);
middleLineHeight = typedArray.getDimension(R.styleable.voiceView_middleLineHeight, 4);
lineSpeed = typedArray.getInt(R.styleable.voiceView_lineSpeed, 90);
fineness = typedArray.getInt(R.styleable.voiceView_fineness, 1);
paths = new ArrayList<>(20);
for (int i = 0; i < 20; i++) {
paths.add(new Path());
}
typedArray.recycle();
    setZOrderOnTop(true);
    getHolder().setFormat(PixelFormat.TRANSLUENT);
    surfaceHolder = getHolder();
    surfaceHolder.addCallback(this);
}
private void drawMiddleLine(Canvas canvas) {
if (paint == null) {
paint = new Paint();
paint.setColor(middleLineColor);
paint.setAntiAlias(true);
}
canvas.save();
canvas.drawRect(0, getHeight() / 2 - middleLineHeight / 2, getWidth(), getHeight() / 2 + middleLineHeight / 2, paint);
canvas.restore();
} private void drawVoiceLine(Canvas canvas) {
lineChange();
if (paintVoicLine == null) {
paintVoicLine = new Paint();
paintVoicLine.setColor(voiceLineColor);
paintVoicLine.setAntiAlias(true);
paintVoicLine.setStyle(Paint.Style.STROKE);
paintVoicLine.setStrokeWidth(2);
}
canvas.save();
int moveY = getHeight() / 2;
for (int i = 0; i < paths.size(); i++) {
paths.get(i).reset();
paths.get(i).moveTo(getWidth(), getHeight() / 2);
}
for (float i = getWidth() - 1; i >= 0; i -= fineness) {
amplitude = 4 * volume * i / getWidth() - 4 * volume * i * i / getWidth() / getWidth();
for (int n = 1; n <= paths.size(); n++) {
float sin = amplitude * (float) Math.sin((i - Math.pow(1.22, n)) * Math.PI / 180 - translateX);
paths.get(n - 1).lineTo(i, (2 * n * sin / paths.size() - 15 * sin / paths.size() + moveY));
}
}
for (int n = 0; n < paths.size(); n++) {
if (n == paths.size() - 1) {
paintVoicLine.setAlpha(255);
} else {
paintVoicLine.setAlpha(n * 130 / paths.size());
}
if (paintVoicLine.getAlpha() > 0) {
canvas.drawPath(paths.get(n), paintVoicLine);
}
}
canvas.restore();
}
public void setVolume(int volume) {
if (volume > maxVolume * sensibility / 25) {
isSet = true;
this.targetVolume = getHeight() * volume / 2 / maxVolume;
}
} private void lineChange() {
if (lastTime == 0) {
lastTime = System.currentTimeMillis();
translateX += 1.5;
} else {
if (System.currentTimeMillis() - lastTime > lineSpeed) {
lastTime = System.currentTimeMillis();
translateX += 1.5;
} else {
return;
}
}
if (volume < targetVolume && isSet) {
volume += getHeight() / 30;
} else {
isSet = false;
if (volume <= 10) {
volume = 10;
} else {
if (volume < getHeight() / 30) {
volume -= getHeight() / 60;
} else {
volume -= getHeight() / 30;
}
}
}
}
@Override
public void surfaceCreated(){
}
@Override
public void surfaceChanged(){
isMiddleLineDrawing = true;
thread = new Thread(this);
thread.start();
}
@Override
public void surfaceDestroyed(){
isMiddleLineDrawing = false;
}
@Override
public void run() {
  while(isMiddleLineDrawing){
    canvas = surfaceHolder.lockCanvas();
    if(canvas==null){
    return;
    }
    canvas.drawColor(Color.TRANSLUENT,PorterDuff.Mode.CLEAR);
    if(isWaveDrawing){
    drawVoiceLine(canvas);
    }
    drawMiddleLine(canvas);
    surfaceHolder.unlockCanvasAndPost(canvas);
  }
} public void setDrawing(boolean drawing){
  isMiddleLineDrawing = true;
  isWaveDrawing = drawing;
} }

最新文章

  1. yield生成器及字符串的格式化
  2. CentOS 6.5 安装 MySQL5.6 并用Navicat for MySQL 连接
  3. ipv4理论知识3-分类编址之两级编址
  4. SQLite入门语句之HAVING和DISTINCT
  5. Android可移动控件
  6. oracle wm_concat(column)函数的使用
  7. win10环境下使用苹果虚拟机不要开多线程应用下载文件
  8. Apache配置虚拟目录和多主机头
  9. sqlplus handbook
  10. poj2762 Going from u to v or from v to u?
  11. 【转载】SQL Server 2008 中新建用户登录并指定该用户的数据库
  12. Android Widget 小部件(四---完结) 使用ListView、GridView、StackView、ViewFlipper展示Widget
  13. Netty(7)源码-ByteBuf
  14. btcpool之Stratum协议
  15. iBatis.Net的基本情况和运行原理
  16. Tesseract 引擎翻译
  17. 原型设计模式 Prototype
  18. hbase 定时备份
  19. BZOJ1935或洛谷2163 [SHOI2007]园丁的烦恼
  20. js生成qq客服在线代码

热门文章

  1. Storm基本概念以及Topology的并发度
  2. centos 7 的安全检查和ip封锁设置
  3. Xamarin XAML语言教程模板视图TemplatedView(一)
  4. Friends number NBUT - 1223 (暴力打表)
  5. Sd - Java多线程
  6. 【转载】R中有关数据挖掘的包
  7. BZOJ 3809 Gty的二逼妹子序列(莫队+分块)
  8. vue-cli创建vue项目
  9. CSS3新增属性2
  10. Problem E: 零起点学算法84——数组中删数II