Пример #1
0
  public SoundLevels(final Context context, final AttributeSet attrs, final int defStyle) {
    super(context, attrs, defStyle);

    // Safe source, replaced with system one when attached.
    mLevelSource = new AudioLevelSource();
    mLevelSource.setSpeechLevel(0);

    final TypedArray a =
        context.obtainStyledAttributes(attrs, R.styleable.SoundLevels, defStyle, 0);

    mMaximumLevelSize = a.getDimensionPixelOffset(R.styleable.SoundLevels_maxLevelRadius, 0);
    mMinimumLevelSize = a.getDimensionPixelOffset(R.styleable.SoundLevels_minLevelRadius, 0);
    mMinimumLevel = mMinimumLevelSize / mMaximumLevelSize;

    mPrimaryLevelPaint = new Paint();
    mPrimaryLevelPaint.setColor(a.getColor(R.styleable.SoundLevels_primaryColor, Color.BLACK));
    mPrimaryLevelPaint.setFlags(Paint.ANTI_ALIAS_FLAG);

    a.recycle();

    // This animator generates ticks that invalidate the
    // view so that the animation is synced with the global animation loop.
    // TODO: We could probably remove this in favor of using postInvalidateOnAnimation
    // which might improve things further.
    mSpeechLevelsAnimator = new TimeAnimator();
    mSpeechLevelsAnimator.setRepeatCount(ObjectAnimator.INFINITE);
    mSpeechLevelsAnimator.setTimeListener(
        new TimeListener() {
          @Override
          public void onTimeUpdate(
              final TimeAnimator animation, final long totalTime, final long deltaTime) {
            invalidate();
          }
        });
  }
Пример #2
0
  @Override
  protected void onDraw(final Canvas canvas) {
    if (!mIsEnabled) {
      return;
    }

    if (!mCenterDefined) {
      // One time computation here, because we can't rely on getWidth() to be computed at
      // constructor time or in onFinishInflate :(.
      mCenterX = getWidth() / 2;
      mCenterY = getWidth() / 2;
      mCenterDefined = true;
    }

    final int level = mLevelSource.getSpeechLevel();
    // Either ease towards the target level, or decay away from it depending on whether
    // its higher or lower than the current.
    if (level > mCurrentVolume) {
      mCurrentVolume = mCurrentVolume + ((level - mCurrentVolume) / 4);
    } else {
      mCurrentVolume = mCurrentVolume * 0.95f;
    }

    final float radius = mMinimumLevel + (1f - mMinimumLevel) * mCurrentVolume / 100;
    mPrimaryLevelPaint.setStyle(Style.FILL);
    canvas.drawCircle(mCenterX, mCenterY, radius * mMaximumLevelSize, mPrimaryLevelPaint);
  }