1.
package com.gome.soundrecorder.views;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.Property;
public class AnswerDrawable extends Drawable{
public static final String TAG = "AnswerDrawable";
public static final int DEFAULT_OUTER_CIRCLE_COLOR = 0xFFFE3B30 ;
public static final int DEFAULT_RING_COLOR = 0xFF3A88FE ;
public static final int DEFAULT_INNER_CIRCLE_COLOR = 0xFFCCCCCC ;
public static final int DEFAULT_RING_WIDTH = 20 ;
public static final int DEFAULT_OUTCIRCLE_WIDTH = 2 ;
public static final int DEFAULT_TEXT_WIDTH = 1 ;
public static final int DEFAULT_TEXT_SIZE = 40 ;
public static final float DEFAULT_CIRCLE_SCALE = 0.85F ;
public static final long DEFAULT_ANIMATION_DURATION = 2360*5 ;
public static final String PROGRESS_PROPERTY = "progress";
private int mRingWidth ;
private int mOutCircleWidth ;
private float mCircleScale ;
private int mOutlineColor ;
private int mRingColor ;
private int mCenterColor ;
private Paint mPaint ;
private Rect mBounds ;
private RectF mArcElements ;
private float mProgress ;
private String mDrawText ;
private IAnswerAnimation mIAnswerAnimation ;
private static final int PROGRESS_FACTOR = 360;
public AnswerDrawable(int ringWidth, float circleScale, int outlineColor, int ringColor, int centerColor, String drawText){
mRingWidth = ringWidth ;
mCircleScale = circleScale ;
mOutlineColor = outlineColor ;
mRingColor = ringColor ;
mCenterColor = centerColor ;
mDrawText = drawText ;
mProgress = 0;
mPaint = new Paint() ;
mPaint.setAntiAlias(true);
mArcElements = new RectF();
mOutCircleWidth = DEFAULT_OUTCIRCLE_WIDTH ;
}
@Override
public void draw(Canvas canvas) {
mBounds = getBounds() ;
int size = Math.min(mBounds.height(), mBounds.width());
float outerRadius = (size / 2) - (mOutCircleWidth / 2);
float innerRadius = outerRadius * mCircleScale;
float offsetX = (mBounds.width() - outerRadius * 2) / 2;
float offsetY = (mBounds.height() - outerRadius * 2) / 2;
// Outline Circle
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(2);
mPaint.setColor(mOutlineColor);
//canvas.drawCircle(mBounds.centerX(), mBounds.centerY(), outerRadius, mPaint);
// Inner circle
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mCenterColor);
canvas.drawCircle(mBounds.centerX(), mBounds.centerY(), innerRadius, mPaint);
int halfRingWidth = mRingWidth / 2;
float arcX0 = offsetX + halfRingWidth;
float arcY0 = offsetY + halfRingWidth;
float arcX = offsetX + outerRadius * 2 - halfRingWidth;
float arcY = offsetY + outerRadius * 2 - halfRingWidth;
// Outer Circle
mPaint.setColor(mRingColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mRingWidth);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mArcElements.set(arcX0, arcY0, arcX, arcY);
canvas.drawArc(mArcElements, -90, mProgress, false, mPaint);
//Text
mPaint.setStrokeWidth(DEFAULT_TEXT_WIDTH);
mPaint.setTextSize(DEFAULT_TEXT_SIZE);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeCap(Paint.Cap.BUTT);
mPaint.setTextAlign(Paint.Align.CENTER);
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
float top = fontMetrics.top;
float bottom = fontMetrics.bottom;
int baseLineY = (int) (mBounds.centerY() - top/2 - bottom/2);
canvas.drawText(mDrawText, mBounds.centerX(), baseLineY, mPaint);
}
public void setOutlineColor(int outlineColor){
mOutlineColor = outlineColor ;
invalidateSelf();
}
public void setCenterColor(int centerColor){
mCenterColor = centerColor ;
invalidateSelf();
}
public void setRingColor(int ringColor) {
mRingColor = ringColor;
invalidateSelf();
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return 1 - mPaint.getAlpha();
}
public float getProgress() {
return mProgress / PROGRESS_FACTOR;
}
public void setProgress(float progress) {
mProgress = PROGRESS_FACTOR * progress;
invalidateSelf();
}
public void setIAnswerAnimation(IAnswerAnimation iAnswerAnimation){
mIAnswerAnimation = iAnswerAnimation ;
}
public void setDrawText(String drawText){
mDrawText = drawText ;
}
public ObjectAnimator startProgressAnimator(){
AnswerDrawableProperty property = new AnswerDrawableProperty(Float.class, PROGRESS_PROPERTY);
ObjectAnimator animator = ObjectAnimator.ofFloat(this, property, 0f,1f);
animator.setDuration(DEFAULT_ANIMATION_DURATION);
//animator.setInterpolator(null);
animator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
setProgress(0f);
}
@Override
public void onAnimationRepeat(Animator animation) {
//nothing
}
@Override
public void onAnimationEnd(Animator animation) {
setProgress(0f);
mIAnswerAnimation.answerAnimationEnd();
}
@Override
public void onAnimationCancel(Animator animation) {
setProgress(0f);
}
});
animator.start();
return animator ;
}
public class AnswerDrawableProperty extends Property<AnswerDrawable,Float>{
public AnswerDrawableProperty(Class<Float> type, String name) {
super(type, name);
}
@Override
public Float get(AnswerDrawable object) {
return object.getProgress();
}
@Override
public void set(AnswerDrawable object, Float value) {
object.setProgress(value);
}
}
public static class Builder{
private int ringWidth = DEFAULT_RING_WIDTH ;
private int outlineColor = DEFAULT_OUTER_CIRCLE_COLOR ;
private int centerColor = DEFAULT_INNER_CIRCLE_COLOR ;
private int ringColor = DEFAULT_RING_COLOR ;
private float circleScale = DEFAULT_CIRCLE_SCALE ;
private String drawText ;
public Builder setRingWidth(int ringWidth) {
this.ringWidth = ringWidth;
return this;
}
public Builder setOutlineColor(int outlineColor) {
this.outlineColor = outlineColor;
return this;
}
public Builder setRingColor(int ringColor) {
this.ringColor = ringColor;
return this;
}
public Builder setCenterColor(int centerColor) {
this.centerColor = centerColor;
return this;
}
public Builder setInnerCircleScale(float circleScale) {
this.circleScale = circleScale;
return this;
}
public Builder setDrawText(String drawText){
this.drawText = drawText;
return this ;
}
public AnswerDrawable create() {
return new AnswerDrawable(ringWidth, circleScale, outlineColor, ringColor, centerColor,drawText);
}
}
public interface IAnswerAnimation{
void answerAnimationEnd();
}
}
2.
package com.gome.soundrecorder.views;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
public class AnswerImageView extends ImageView
implements android.view.View.OnLongClickListener,android.view.View.OnClickListener,AnswerDrawable.IAnswerAnimation{
private static final String TAG = "AnswerImageView";
private IAnswerHandler mIAnswerHandler ;
public AnswerImageView(Context context) {
super(context);
init();
}
public AnswerImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public AnswerImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public AnswerImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public void setIAnswerHandler(IAnswerHandler iAnswerHandler){
mIAnswerHandler = iAnswerHandler ;
}
private void init(){
setEnabled(true);
setClickable(true);
setLongClickable(true);
setHapticFeedbackEnabled(true);
setOnLongClickListener(this);
setOnClickListener(this);
setOnTouchListener(answerTouchListener);
}
@Override
public boolean onLongClick(View v) {
mIAnswerHandler.doAnswerStart();
return false;
}
@Override
public void onClick(View v) {
mIAnswerHandler.doAnswerStop();
}
private OnTouchListener answerTouchListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getActionMasked() ;
switch(action){
case MotionEvent.ACTION_MOVE:
//handle cancel recording
break ;
case MotionEvent.ACTION_CANCEL:
mIAnswerHandler.doAnswerCancel();
break ;
}
return false;
}
};
public interface IAnswerHandler{
void doAnswerStart();
void doAnswerStop();
void doAnswerCancel();
}
@Override
public void answerAnimationEnd() {
mIAnswerHandler.doAnswerStop();
}
3.
@Override
public void doAnswerStart() {
mAnswerAnimation = mAnswerDrawable.startProgressAnimator();
onClickRecordButton();
}
@Override
public void doAnswerStop() {
mAnswerAnimation.cancel();
onClickPauseRecordingButton();
saveOrCancle();
}
@Override
public void doAnswerCancel() {
mAnswerAnimation.cancel();
onClickStopButton();
}