许久不来 , 冒个泡 , 发一个刚做的声音波动的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 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();  }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多相关文章

  1. android中pull解析xml和生成xml
  2. Android(安卓)给图标着色的方法
  3. Android(安卓)studio 生成 lib.so
  4. [填坑系列]Android(安卓)Studio 3.0配置更改
  5. Ionic 程序打包发布Android版本
  6. Android(安卓)Studio 打包发布apk
  7. 如何申请个人Google API Key用于Android真机上发布安装
  8. Android(安卓)Handler机制总结
  9. Android(安卓)原代码编后的目录分析

随机推荐

  1. Bug!Redis 6.0.8紧急发布,请尽快升级!
  2. 超赞!墙裂推荐一个 MySQL 自动化运维工具!
  3. 介绍一个可以离线查询 IP 来源和 ISP 信
  4. 史上首例!阿里程序员写的这三行代码,被国家
  5. 时间同步、双因子安全验证及自动化安装实
  6. 2021年全新永久有效Phpstorm激活码
  7. tp6 多文件上传
  8. 网络发展遭遇瓶颈期,如何推动SDN/NFV解决
  9. Ansible Playbook详解
  10. 超实用案例:美团终端主动监控平台的建设