Android Open Source - paperchains Audio Recorder Circle Button






From Project

Back to project page paperchains.

License

The source code is released under:

Apache License

If you think the Android project paperchains listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (c) 2014 Markus Hi/*from   www. java2 s .com*/
 * Portions copyright (c) 2014 Simon Robinson
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ac.robinson.paperchains;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;

import com.github.lassana.recorder.AudioRecorder;
import com.nineoldandroids.animation.ObjectAnimator;

public class AudioRecorderCircleButton extends ImageView {

  private static final int PRESSED_COLOR_LIGHTUP = 255 / 25;
  private static final int PRESSED_RING_ALPHA = 75;
  private static final int DEFAULT_PRESSED_RING_WIDTH_DIP = 4;
  private static final int DEFAULT_RECORDING_RING_WIDTH_DIP = 0; // default to not shown
  private static final int PRESSED_ANIMATION_TIME_ID = android.R.integer.config_shortAnimTime;
  private static final int RECORDING_ANIMATION_TIME_ID = android.R.integer.config_longAnimTime;

  private int centerY;
  private int centerX;
  private int outerRadius;
  private int pressedRingRadius;
  private int recordingRingRadius;

  private Paint circlePaint;
  private Paint focusPaint;
  private Paint recordingPaint;

  private float pressedAnimationProgress;
  private float recordingAnimationProgress;

  private int pressedRingWidth;
  private int recordingRingWidth;
  private int radiusCorrection;

  private int defaultColor = Color.BLACK;
  private int pressedColor;

  private ObjectAnimator pressedAnimator;
  private ObjectAnimator recordingAnimator;

  private AudioRecorder audioRecorder;
  private float currentAmplitude;
  private boolean hasHiddenRecordingRing;

  public AudioRecorderCircleButton(Context context) {
    super(context);
    init(context, null);
  }

  public AudioRecorderCircleButton(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
  }

  public AudioRecorderCircleButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context, attrs);
  }

  @Override
  public void setPressed(boolean pressed) {
    super.setPressed(pressed);

    if (circlePaint != null) {
      circlePaint.setColor(pressed ? pressedColor : defaultColor);
    }

    if (pressed) {
      showPressedRing();
    } else {
      hidePressedRing();
    }
  }

  @Override
  protected void onDraw(@NonNull Canvas canvas) {
    if (audioRecorder != null && audioRecorder.isRecording()) {
      canvas.drawCircle(centerX, centerY, recordingRingRadius + recordingAnimationProgress, recordingPaint);

      float newAmplitude = audioRecorder.getMaxAmplitude() / 16384f;
      if (newAmplitude - currentAmplitude > 0.1) {
        currentAmplitude = newAmplitude;
        showRecordingRing();
      } else if (!hasHiddenRecordingRing) {
        hideRecordingRing();
      } else {
        postInvalidateDelayed(recordingAnimator.getDuration());
      }
      currentAmplitude *= 0.82;
    }
    canvas.drawCircle(centerX, centerY, pressedRingRadius + pressedAnimationProgress, focusPaint);
    canvas.drawCircle(centerX, centerY, outerRadius - radiusCorrection, circlePaint);
    super.onDraw(canvas);
  }

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    centerX = w / 2;
    centerY = h / 2;
    outerRadius = Math.min(w, h) / 2;

    radiusCorrection = Math.max(pressedRingWidth, recordingRingWidth);
    pressedRingRadius = outerRadius - radiusCorrection - pressedRingWidth / 2;
    recordingRingRadius = outerRadius - radiusCorrection - recordingRingWidth / 2;
  }

  @SuppressWarnings("UnusedDeclaration")
  public float getPressedAnimationProgress() {
    return pressedAnimationProgress;
  }

  @SuppressWarnings("UnusedDeclaration")
  public void setPressedAnimationProgress(float pressedAnimationProgress) {
    this.pressedAnimationProgress = pressedAnimationProgress;
    this.invalidate();
  }

  @SuppressWarnings("UnusedDeclaration")
  public float getRecordingAnimationProgress() {
    return recordingAnimationProgress;
  }

  @SuppressWarnings("UnusedDeclaration")
  public void setRecordingAnimationProgress(float recordingAnimationProgress) {
    this.recordingAnimationProgress = recordingAnimationProgress;
    this.invalidate();
  }

  public void setRecorder(AudioRecorder recorder) {
    audioRecorder = recorder;
    this.invalidate();
  }

  private void setColors(int pressedColor, int recordingColor) {
    this.defaultColor = pressedColor;
    this.pressedColor = getHighlightColor(pressedColor, PRESSED_COLOR_LIGHTUP);

    circlePaint.setColor(defaultColor);
    focusPaint.setColor(defaultColor);
    focusPaint.setAlpha(PRESSED_RING_ALPHA);

    recordingPaint.setColor(recordingColor);
    recordingPaint.setAlpha(PRESSED_RING_ALPHA);

    this.invalidate();
  }

  private void hidePressedRing() {
    pressedAnimator.setFloatValues(pressedRingWidth, 0f);
    pressedAnimator.start();
  }

  private void showPressedRing() {
    pressedAnimator.setFloatValues(pressedAnimationProgress, pressedRingWidth);
    pressedAnimator.start();
  }

  private void hideRecordingRing() {
    hasHiddenRecordingRing = true;
    recordingAnimator.setFloatValues(recordingRingWidth, 0f);
    recordingAnimator.start();
  }

  private void showRecordingRing() {
    hasHiddenRecordingRing = false;
    recordingAnimator.setFloatValues(recordingAnimationProgress, recordingRingWidth);
    recordingAnimator.start();
  }

  private void init(Context context, AttributeSet attrs) {
    this.setFocusable(true);
    this.setScaleType(ScaleType.CENTER_INSIDE);
    setClickable(true);

    circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    circlePaint.setStyle(Paint.Style.FILL);

    focusPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    focusPaint.setStyle(Paint.Style.STROKE);

    recordingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    recordingPaint.setStyle(Paint.Style.STROKE);

    pressedRingWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
        DEFAULT_PRESSED_RING_WIDTH_DIP, getResources().getDisplayMetrics());

    recordingRingWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
        DEFAULT_RECORDING_RING_WIDTH_DIP, getResources().getDisplayMetrics());

    int pressedColor = Color.BLACK;
    int recordingColor = Color.BLACK;
    if (attrs != null) {
      final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AudioRecorderCircleButton);
      pressedColor = a.getColor(R.styleable.AudioRecorderCircleButton_cb_pressedColor, pressedColor);
      recordingColor = a.getColor(R.styleable.AudioRecorderCircleButton_cb_recordingColor, recordingColor);
      pressedRingWidth = (int) a.getDimension(R.styleable.AudioRecorderCircleButton_cb_pressedRingWidth,
          pressedRingWidth);
      recordingRingWidth = (int) a.getDimension(R.styleable.AudioRecorderCircleButton_cb_recordingRingWidth,
          recordingRingWidth);
      a.recycle();
    }

    setColors(pressedColor, recordingColor);

    focusPaint.setStrokeWidth(pressedRingWidth);
    recordingPaint.setStrokeWidth(recordingRingWidth);

    final int pressedAnimationTime = getResources().getInteger(PRESSED_ANIMATION_TIME_ID);
    pressedAnimator = ObjectAnimator.ofFloat(this, "pressedAnimationProgress", 0f, 0f);
    pressedAnimator.setDuration(pressedAnimationTime);

    final int recordingAnimationTime = getResources().getInteger(RECORDING_ANIMATION_TIME_ID);
    recordingAnimator = ObjectAnimator.ofFloat(this, "recordingAnimationProgress", 0f, 0f);
    recordingAnimator.setDuration(recordingAnimationTime);
  }

  private int getHighlightColor(int color, @SuppressWarnings("SameParameterValue") int amount) {
    return Color.argb(Math.min(255, Color.alpha(color)), Math.min(255, Color.red(color) + amount), Math.min(255,
        Color.green(color) + amount), Math.min(255, Color.blue(color) + amount));
  }
}




Java Source Code List

ac.robinson.paperchains.AudioRecorderCircleButton.java
ac.robinson.paperchains.PaperChainsActivity.java
ac.robinson.paperchains.PaperChainsView.java
ac.robinson.paperchains.SoundCloudLoginActivity.java
ac.robinson.paperchains.SoundCloudUploadTask.java
ac.robinson.paperchains.SoundCloudUrlFetcherTask.java
com.github.lassana.recorder.ApiHelper.java
com.github.lassana.recorder.AudioRecorder.java
com.github.lassana.recorder.Mp4ParserWrapper.java
com.sonyericsson.zoom.AspectQuotient.java
com.sonyericsson.zoom.DynamicZoomControl.java
com.sonyericsson.zoom.Dynamics.java
com.sonyericsson.zoom.LongPressZoomListener.java
com.sonyericsson.zoom.SpringDynamics.java
com.sonyericsson.zoom.ZoomState.java
com.soundcloud.playerapi.ApiWrapper.java
com.soundcloud.playerapi.CloudAPI.java
com.soundcloud.playerapi.CountingMultipartEntity.java
com.soundcloud.playerapi.DecompressingEntity.java
com.soundcloud.playerapi.Endpoints.java
com.soundcloud.playerapi.Env.java
com.soundcloud.playerapi.GzipDecompressingEntity.java
com.soundcloud.playerapi.Http.java
com.soundcloud.playerapi.OAuth2HttpRequestInterceptor.java
com.soundcloud.playerapi.OAuth2Scheme.java
com.soundcloud.playerapi.Params.java
com.soundcloud.playerapi.Request.java
com.soundcloud.playerapi.Stream.java
com.soundcloud.playerapi.Token.java