美文网首页
微信拍照录像自定义view实现

微信拍照录像自定义view实现

作者: Mylovesunshine | 来源:发表于2019-08-28 15:29 被阅读0次

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class CamereView extends View {
private Paint mPaint;
private float outRadius = 110;
private float inRadius = 80;
private int button_size = 110;
private int outside_add_size = 10;
private int inside_reduce_size;
int center_X;
int center_Y;
private int progress_color = 0xEE16AE16; //进度条颜色
private int outside_color = 0x80ffffff; //外圆背景色
private int inside_color = 0xFFFFFFFF;
private RectF rectF;
private float currentProgress = 0;
private float event_Y;
private int state;
public static final int STATE_IDLE = 0x001; //空闲状态
public static final int STATE_PRESS = 0x002; //按下状态
public static final int STATE_LONG_PRESS = 0x003; //长按状态
public static final int STATE_RECORDERING = 0x004; //录制状态
public static final int STATE_BAN = 0x005; //禁止状态
private LongRunnable longRunnable;
private int duration; //录制视频最大时间长度
private int min_duration; //最短录制时间限制
private int recorded_time; //记录当前录制的时间
private RecordCountDownTimer timer;
private int width;
private int height;
private int strokeWidth = 10;

public CamereView(Context context) {
    super(context);
}

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

//float left, float top, float right, float bottom
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    center_X = w / 2;
    center_Y = h - (int) outRadius;
    width = w;
    height = h;
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    mPaint.setColor(outside_color);
    canvas.drawCircle(center_X, center_Y, outRadius, mPaint);
    mPaint.setColor(inside_color);
    canvas.drawCircle(center_X, center_Y, inRadius, mPaint);
    if (state == STATE_RECORDERING) {
        Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setAntiAlias(true);
        mPaint.setColor(progress_color);
        mPaint.setStrokeWidth(strokeWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawArc(rectF, -90, currentProgress, false, mPaint);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            event_Y = event.getY();
            if (event.getPointerCount() > 1 && state != STATE_IDLE) {
                break;
            }
            state = STATE_PRESS;
            postDelayed(longRunnable, 500);
            break;
        case MotionEvent.ACTION_UP:
            handlerUnpressByState();
            break;
    }
    return true;
}

//当手指松开按钮时候处理的逻辑
private void handlerUnpressByState() {
    removeCallbacks(longRunnable); //移除长按逻辑的Runnable
    //根据当前状态处理
    switch (state) {
        //当前是点击按下
        case STATE_PRESS:
            startCaptureAnimation(inRadius);
            state = STATE_IDLE;
            break;
        //当前是长按状态
        case STATE_RECORDERING:
            timer.cancel(); //停止计时器
            recordEnd();    //录制结束
            break;
    }
}

//内圆动画
private void startCaptureAnimation(float inside_start) {
    ValueAnimator inside_anim = ValueAnimator.ofFloat(inside_start, inside_start * 0.55f, inside_start);
    inside_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            inRadius = (float) animation.getAnimatedValue();
            invalidate();
        }
    });
    inside_anim.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            //回调拍照接口
            state = STATE_BAN;
        }
    });
    inside_anim.setDuration(100);
    inside_anim.start();
}

private void init() {
    getPaint();
    duration = 10 * 1000;
    min_duration = 1500;
    longRunnable = new LongRunnable();
    timer = new RecordCountDownTimer(duration, duration / 360);    //录制定时器
    state = STATE_IDLE;
    mPaint.setStyle(Paint.Style.FILL);

}

private void getPaint() {
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setAntiAlias(true);
}

private class LongRunnable implements Runnable {
    @Override
    public void run() {
        state = STATE_LONG_PRESS;
        center_Y = height - button_size - outside_add_size;
        rectF = new RectF(width / 2 - button_size - outside_add_size + strokeWidth / 2, center_Y - button_size - outside_add_size / 2, width / 2 + button_size - strokeWidth / 2 + outside_add_size, center_Y + button_size + outside_add_size / 2);
        startRecordAnimation(outRadius, outRadius + outside_add_size, inRadius, inRadius - inRadius / 2);
    }
}

//更新进度条
private void updateProgress(long millisUntilFinished) {
    recorded_time = (int) (duration - millisUntilFinished);
    currentProgress = 360f - millisUntilFinished / (float) duration * 360f;
    invalidate();
}

//内外圆动画
private void startRecordAnimation(float outside_start, float outside_end, float inside_start, float inside_end) {
    ValueAnimator outside_anim = ValueAnimator.ofFloat(outside_start, outside_end);
    ValueAnimator inside_anim = ValueAnimator.ofFloat(inside_start, inside_end);
    //外圆动画监听
    outside_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            outRadius = (float) animation.getAnimatedValue();
            invalidate();
        }
    });
    //内圆动画监听
    inside_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            inRadius = (float) animation.getAnimatedValue();
            invalidate();
        }
    });
    AnimatorSet set = new AnimatorSet();
    //当动画结束后启动录像Runnable并且回调录像开始接口
    set.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            //设置为录制状态
            if (state == STATE_LONG_PRESS) {
                state = STATE_RECORDERING;
                timer.start();
            }
        }
    });
    set.playTogether(outside_anim, inside_anim);
    set.setDuration(100);
    set.start();
}

//录制视频计时器
private class RecordCountDownTimer extends CountDownTimer {
    RecordCountDownTimer(long millisInFuture, long countDownInterval) {
        super(millisInFuture, countDownInterval);
    }

    @Override
    public void onTick(long millisUntilFinished) {
        updateProgress(millisUntilFinished);
    }

    @Override
    public void onFinish() {
        updateProgress(0);
        recordEnd();
    }
}

private void recordEnd() {
    //重置和
    inRadius = 80;
    outRadius = button_size;
    startRecordAnimation(outRadius, outRadius, inRadius, inRadius);
    state = STATE_IDLE;

}

}

相关文章

网友评论

      本文标题:微信拍照录像自定义view实现

      本文链接:https://www.haomeiwen.com/subject/xoxmectx.html