@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); }