Android语音声波控件 Android条形波控件

作者:长脸先生 时间:2023-10-29 02:03:05 

许久不来 , 冒个泡 , 发一个刚做的声音波动的View吧 :

代码不多 , 没什么技术含量 , 权当给您省时间了 , 直接复制粘贴就能用 , 直接上代码:

SoundWavesView


/**
* 语音通话的声波控件
* Created by Mr.LongFace on 2017/9/16.
*/
public class SoundWavesView extends View {

private int mMini; // 最短值
 private int mMax; // 最大值
 private int mLineWidth; // 每条声波的宽度
 private int mSoundNum = 5; // 声波的数量
 private int mSpac; // 每条声波的中点
 private int mWidth , mHeight; // 控件宽高
 private boolean isRun = false;

private Paint mPaint;
 private RectF mRectF;
 private List<SoundLine> mSoundList = new ArrayList<>();
 private Handler mHandler = new Handler();
 private Runnable mInvalidateRun = new Runnable() {
   @Override
   public void run() {
     postInvalidate();
   }
 };

public SoundWavesView(Context context, @Nullable AttributeSet attrs) {
   super(context, attrs);
   mPaint = new Paint();
   mPaint.setAntiAlias(true);
   mPaint.setColor(getResources().getColor(R.color.color_red));
   mPaint.setStyle(Paint.Style.FILL);
   mRectF = new RectF();
 }

@Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   super.onMeasure(widthMeasureSpec, heightMeasureSpec);
   if (widthMeasureSpec > 0 && heightMeasureSpec > 0) {
     initParam();
   }
 }

private void initParam() {
   mWidth = getWidth();
   mHeight = getHeight();
   mMini = (int) (mHeight * 0.3f);
   mMax = mHeight;
   initLines();
 }

@Override
 protected void onDraw(Canvas canvas) {
   super.onDraw(canvas);
   for (int i = 0; i < mSoundNum; i++) {
     SoundLine sound = mSoundList.get(i);
     mRectF.left = sound.left;
     mRectF.right = sound.right;
     mRectF.top = sound.top;
     mRectF.bottom = sound.bottom;
     canvas.drawRoundRect(mRectF , mLineWidth / 2 , mLineWidth / 2 , mPaint);
   }
   if (isRun) {
     mHandler.postDelayed(mInvalidateRun, 10);
   }
 }

@Override
 protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
   super.onVisibilityChanged(changedView, visibility);
   if (isRun) {
     if (visibility == VISIBLE) {
       if (mWidth == 0) {
         initParam();
       }
       if (mSoundList != null && mSoundList.size() > 0) {
         for (SoundLine soundLine : mSoundList) {
           soundLine.start();
         }
       }
     }else{
       if (mSoundList != null && mSoundList.size() > 0) {
         for (SoundLine soundLine : mSoundList) {
           soundLine.stop();
         }
       }
     }
   }
 }

public void start() {
   if (!isRun) {
     isRun = true;
     for (SoundLine sound : mSoundList) {
       sound.start();
     }
     postInvalidate();
   }
 }

public void stop(){
   if (isRun) {
     isRun = false;
     for (SoundLine sound : mSoundList) {
       sound.stop();
     }
   }
 }

private void initLines() {
   mLineWidth = (int) (mWidth / mSoundNum * 0.7f);
   mSpac = mWidth / (mSoundNum - 1);
   mSoundList.clear();
   chaos();
 }

/**
  * 生成凌乱的
  */
 private void chaos() {
   for (int i = 0; i < mSoundNum; i++) {
     int left = i * mSpac - mLineWidth / 2;
     int right = i * mSpac + mLineWidth / 2;
     SoundLine s = new SoundLine(left , right , 0 , mHeight);
     s.setMode(SoundLine.SPEED_RAN);
     s.setBorder(mMini , mMax);
     mSoundList.add(s);
   }
 }

/**
  * 生成波浪的
  */
 private void wave(){
   // TODO 防止UI抽风
 }

/**
  * 生成有序的
  */
 private void order(){
   // TODO 防止UI抽风
 }
}

SoundLine


/**
* 语音音频波纹的单个音波属性
* Created by Mr.LongFace on 2017/9/16.
*/
public class SoundLine implements ValueAnimator.AnimatorUpdateListener{

// 低 中 高 随机 4挡
 public static final int SPEED_LOW = 500;
 public static final int SPEED_MID = 200;
 public static final int SPEED_HEI = 0;
 public static final int SPEED_RAN = 0;

private Random mRandom;
 private ValueAnimator mAnim;

public int left , right , top , bottom;
 private int min , max;

public SoundLine(int left , int right , int top , int bottom){
   this.left = left;
   this.right = right;
   this.top = top;
   this.bottom = bottom;
   mRandom = new Random();
   initAnim();
 }

private void initAnim() {
   mAnim = ValueAnimator.ofFloat(0.0f , 1.0f);
   setMode(SPEED_MID);
   mAnim.setRepeatCount(-1);
   mAnim.setRepeatMode(ValueAnimator.REVERSE);
   mAnim.addUpdateListener(this);
 }

public void setMode(int mode){
   if (mode == SPEED_RAN) {
     mode = mRandom.nextInt(400);
   }
   mAnim.setDuration(300 + mode);
 }

public void start(){
   if (mAnim.isRunning()){
     mAnim.end();
   }
   mAnim.start();
 }

@Override
 public void onAnimationUpdate(ValueAnimator valueAnimator) {
   float f = (float) valueAnimator.getAnimatedValue();
   top = (int) (f * (max - min) / 2);
   bottom = max - top;
 }

public void setBorder(int min, int max) {
   this.min = min;
   this.max = max;
 }

public void stop() {
   mAnim.end();
   mAnim.cancel();
 }
}

来源:http://blog.csdn.net/u012984054/article/details/78029578

标签:Android,声波控件,条形波控件
0
投稿

猜你喜欢

  • android6.0权限动态申请框架permissiondispatcher的方法

    2023-07-31 10:51:57
  • vista和win7在windows服务中交互桌面权限问题解决方法:穿透Session 0 隔离

    2021-06-16 04:05:47
  • C#实现将RTF转为HTML的示例代码

    2023-11-14 02:32:18
  • 解决FeignClient重试机制造成的接口幂等性

    2022-01-25 11:10:35
  • Android点击WebView实现图片缩放及滑动浏览效果

    2021-12-12 19:32:48
  • Java调用WebService接口作测试

    2023-08-11 17:00:20
  • Android Studio使用Kotlin时,修改代码后运行不生效的解决方法

    2022-08-05 11:29:04
  • 解决pageHelper分页失效以及如何配置问题

    2022-03-15 06:45:44
  • Android 实现定时器的四种方式总结及实现实例

    2023-04-20 15:22:04
  • WPF实现控件拖动的示例代码

    2023-04-01 09:36:15
  • C#应用BindingSource实现数据同步的方法

    2021-07-09 16:15:48
  • Jmeter分布式压力测试实现过程详解

    2022-03-23 21:32:44
  • Android应用中图片浏览时实现自动切换功能的方法详解

    2023-04-13 15:34:00
  • c#多线程的应用全面解析

    2023-03-03 21:15:02
  • Spark学习笔记之Spark中的RDD的具体使用

    2023-07-05 04:49:44
  • Java设计模式之java装饰者模式详解

    2023-10-27 06:17:04
  • Android按钮单击事件的四种常用写法总结

    2023-07-15 09:05:18
  • Springboot @Configuration @bean注解作用解析

    2022-11-05 01:58:47
  • Android 虚拟按键与沉浸式的适配方法

    2021-11-27 22:03:02
  • java实现按层遍历二叉树

    2021-12-04 06:58:35
  • asp之家 软件编程 m.aspxhome.com