最近做了一个小的项目,涉及的android 画wav文件的波形图。下面给出自定义view的示例:
package com.example.showwave.view;
import android.R.integer;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
public class WaveView extends View {
private float[] audioData = null;
private int width = 0;
private int height = 400;
public void setWidth(int width){
this.width = width;
}
public void setHeight(int height){
this.height = height;
}
private Paint paint;
private Paint paint1;
public WaveView(Context context) {
super(context);
this.paint = new Paint();
this.paint1 = new Paint();
}
public WaveView(Context context, AttributeSet attrs) {
super(context, attrs);
this.paint = new Paint();
this.paint1 = new Paint();
}
public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.paint = new Paint();
this.paint1 = new Paint();
}
@Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.BLACK);
// 设置字体大小
paint.setTextSize(25);
// 让画出的图形是空心的
paint.setStyle(Paint.Style.FILL);
// 设置画出的线的 粗细程度
paint.setStrokeWidth(1);
paint1.setColor(Color.BLUE);
paint1.setTextSize(25);
paint1.setStyle(Paint.Style.FILL);
canvas.drawText("y", 10, 30, paint);
canvas.drawText("x", width-140, 40+height/2, paint);
drawAL(10, 40+height/2, width-150, 40+height/2, canvas);
drawAL(10, 40+height, 10, 30, canvas);
canvas.drawText("左声道", width-180, 75, paint);
canvas.drawText("右声道", width-180, 115, paint);
paint.setColor(Color.RED);
canvas.drawLine(width-300, 70, width-200, 70, paint);
canvas.drawLine(width-300, 110, width-200, 110, paint1);
double ratio = (double)(width-200)/512;
if (audioData != null) {
for (int i = 0; i < audioData.length - 1; i++) {
canvas.drawLine((float) (i*ratio+10), audioData[i] + 40+height/2, (float) ((i+1)*ratio+10), audioData[i + 1] + 40+height/2, paint);
}
}
super.onDraw(canvas);
}
public void setAudioData(float[] aduioData) {
this.audioData = aduioData;
invalidate();
}
/**
*
* @param canvas
* @param p1
* 周期大小
* @param p2
* 采样点数
*/
public void drawSin(Canvas canvas, int p1, int p2) {
float[] x = new float[p2];
float[] y = new float[p2];
double Pi = 2 * Math.PI;
float t1 = (float) 390 / p2;
x[0] = 10;
y[0] = 280;
for (int i = 1; i < p2; i++) {
x[i] = (i * t1) + 10;
y[i] = -(float) Math.sin(i * t1 * Pi / p1) * 70 + 280;
canvas.drawLine(x[i - 1], y[i - 1], x[i], y[i], paint);
}
}
/**
* 画箭头
*
* @param sx
* @param sy
* @param ex
* @param ey
*/
public void drawAL(int sx, int sy, int ex, int ey, Canvas canvas) {
double H = 8; // 箭头高度
double L = 3.5; // 底边的一半
int x3 = 0;
int y3 = 0;
int x4 = 0;
int y4 = 0;
double awrad = Math.atan(L / H); // 箭头角度
double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
double y_3 = ey - arrXY_1[1];
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
double y_4 = ey - arrXY_2[1];
Double X3 = new Double(x_3);
x3 = X3.intValue();
Double Y3 = new Double(y_3);
y3 = Y3.intValue();
Double X4 = new Double(x_4);
x4 = X4.intValue();
Double Y4 = new Double(y_4);
y4 = Y4.intValue();
// 画线
canvas.drawLine(sx, sy, ex, ey, paint);
Path triangle = new Path();
triangle.moveTo(ex, ey);
triangle.lineTo(x3, y3);
triangle.lineTo(x4, y4);
triangle.close();
canvas.drawPath(triangle, paint);
}
// 计算
public double[] rotateVec(int px, int py, double ang, boolean isChLen,
double newLen) {
double mathstr[] = new double[2];
// 矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
double vx = px * Math.cos(ang) - py * Math.sin(ang);
double vy = px * Math.sin(ang) + py * Math.cos(ang);
if (isChLen) {
double d = Math.sqrt(vx * vx + vy * vy);
vx = vx / d * newLen;
vy = vy / d * newLen;
mathstr[0] = vx;
mathstr[1] = vy;
}
return mathstr;
}
}