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

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

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

(0)

相关推荐

  • Android实现水波纹控件的方法

    有很多app使用过水波纹的这样的效果,看着很酷酷的样子,所以自己就撸码写了一个. 实现思路: 利用贝塞尔曲线绘制圆弧(也就是水波的波纹) 通过动画改变绘制的起始点使水波纹平移 首先,定义我们需要的自定义属性. <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="waveStyleable"> <!-- 水波

  • android球形水波百分比控件代码

    本文主要介绍的是一个球形水波的百分比控件,市面上有各种形形色色的百分比控件,我一直觉得水波是最炫的,UI给了我这个机会,然而网上搜了一大堆,不是太复杂,代码太多(反正我是调不出效果来),就是有瑕疵的,所以只好自己写了,这里开源出来,方便大家.有什么问题或者建议大家留言指出. 先看效果,这里动态图不好截取,就贴张静态的 对于水波百分比控件实现方法有如下几种 - 画好水波形状的bitmap,利用属性动画进行平移 - 利用曲线精确绘制目标水波 - 利用大范围曲线与容器做交集 第一种比较烦,网上有这种思

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

    许久不来 , 冒个泡 , 发一个刚做的声音波动的View吧 : 代码不多 , 没什么技术含量 , 权当给您省时间了 , 直接复制粘贴就能用 , 直接上代码: SoundWavesView /** * 语音通话的声波控件 * Created by Mr.LongFace on 2017/9/16. */ public class SoundWavesView extends View { private int mMini; // 最短值 private int mMax; // 最大值 priv

  • Android下拉刷新上拉加载控件(适用于所有View)

    前面写过一篇关于下拉刷新控件的文章下拉刷新控件终结者:PullToRefreshLayout,后来看到好多人还有上拉加载更多的需求,于是就在前面下拉刷新控件的基础上进行了改进,加了上拉加载的功能.不仅如此,我已经把它改成了对所有View都通用!可以随心所欲使用这两个功能~~ 我做了一个大集合的demo,实现了ListView.GridView.ExpandableListView.ScrollView.WebView.ImageView.TextView的下拉刷新和上拉加载.后面会提供demo的

  • Android开发之无痕过渡下拉刷新控件的实现思路详解

    相信大家已经对下拉刷新熟悉得不能再熟悉了,市面上的下拉刷新琳琅满目,然而有很多在我看来略有缺陷,接下来我将说明一下存在的缺陷问题,然后提供一种思路来解决这一缺陷,废话不多说!往下看嘞! 1.市面一些下拉刷新控件普遍缺陷演示 以直播吧APP为例: 第1种情况: 滑动控件在初始的0位置时,手势往下滑动然后再往上滑动,可以看到滑动到初始位置时滑动控件不能滑动. 原因: 下拉刷新控件响应了触摸事件,后续的一系列事件都由它来处理,当滑动控件到顶端的时候,滑动事件都被下拉刷新控件消费掉了,传递不到它的子控件

  • Android自定义控件实现简单的轮播图控件

    最近要做一个轮播图的效果,网上看了几篇文章,基本上都能找到实现,效果还挺不错,但是在写的时候感觉每次都要单独去重新在Activity里写一堆代码.于是自己封装了一下.本篇轮播图实现原理原文出处:循环广告位组件的实现,这里只是做了下封装成一个控件,不必每次重复写代码了. 效果图: 实现分析 轮播图的功能就是实现左右滑动的广告.图片信息展示,那我们就用ViewPager来实现,由于考虑到用户体验,我们还需要在下面加一个指示器来标示滑动到了第几张轮播图.指示器我们可以用一个线性布局来根据要展示的轮播图

  • android实现图片验证码方法解析(自绘控件)

    自绘控件的内容都是自己绘制出来的 大致流程如下: 1.定义一个类继承view 1.使用TypedArray初始化属性集合     在view的构造方法中 有一个AttributeSet的参数 很明显是用来保存控件属性信息的 我们也的确可以通过循环然后用键值对的方式获取信息 而TypedArray是用来简化我们的工作的 2.重写onMeasure 测量控件大小 3.重写onDraw 绘制控件 2.根据需求在attrs文件中自定义属性 declare-styleable 声明自定义属性可以自定义一个

  • Android编程获取屏幕宽高与获取控件宽高的方法

    本文实例讲述了Android编程获取屏幕宽高与获取控件宽高的方法.分享给大家供大家参考,具体如下: 获取屏幕宽高 // 获取屏幕宽高(方法1) int screenWidth = getWindowManager().getDefaultDisplay().getWidth(); // 屏幕宽(像素,如:480px) int screenHeight = getWindowManager().getDefaultDisplay().getHeight(); // 屏幕高(像素,如:800p) L

  • Android编程实现点击EditText之外的控件隐藏软键盘功能

    本文实例讲述了Android编程实现点击EditText之外的控件隐藏软键盘功能.分享给大家供大家参考,具体如下: 工具类 ... public static void hideKeyboard(Context ctx) { if (ctx != null) { View view = ((Activity) ctx).getCurrentFocus(); if (view != null) { InputMethodManager inputManager = (InputMethodMana

  • Android仿英语流利说取词放大控件的实现方法(附demo源码下载)

    本文实例讲述了Android仿英语流利说取词放大控件的实现方法.分享给大家供大家参考,具体如下: 1 取词放大控件 英语流利说是一款非常帮的口语学习app,在app的修炼页面长按屏幕,会弹出一个放大镜,当手指移到某个单词的附近,可以看到该英文单词会被选中,效果如下图所示: 2 代码示例 该控件挺有意思,于是我写了个简单的demo,完整实例代码点击此处本站下载.,程序运行后的效果如下: 3 实现原理 该控件的实现原理比较简单,下面介绍几个比较重要的类 ① WordView 在实习该控件的过程中,我

  • Android自定义控件之创建可复用的组合控件

    前面已学习了一种自定义控件的实现,是Andriod 自定义控件之音频条,还没学习的同学可以学习下,学习了的同学也要去温习下,一定要自己完全的掌握了,再继续学习,贪多嚼不烂可不是好的学习方法,我们争取学习了一种技术就会一种技术,而且不光看了就算了,最好的方法就是看完我自己再练习下,再扩展下,在原来的基础上在添加一些东西,比如,增加一些功能实现等等. 今天我们打算学习下另外一种自定义控件,就是创建可重复使用的组合控件,那么问题来了: 什么是可重复使用? 就是在应用中,可以在多个地方共同使用一套代码.

  • Android编程实现图片放大缩小功能ZoomControls控件用法实例

    本文实例讲述了Android编程实现图片放大缩小功能ZoomControls控件用法.分享给大家供大家参考,具体如下: MainActivity代码: package example.com.myapplication; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import

随机推荐