【Android】Jetpack全组件实战开发短视频应用App(二十二)

前言

项目地址.
这一篇我们主要是完成自定义录制RecordView,页面很简单,就长下面那样,我们点击一下是拍照,按住就开始录制,录制需要进度条,进度条满或者松手表示录制完成
【Android】Jetpack全组件实战开发短视频应用App(二十二)_第1张图片

实现

首先我们定义几个属性

<declare-styleable name="RecordView">
		//进度条颜色
        <attr name="progress_color" format="color">attr>
        //进度条宽度
        <attr name="progress_width" format="dimension">attr>
        //按钮填充颜色
        <attr name="fill_color" format="color">attr>
        //按钮的半径
        <attr name="radius" format="dimension">attr>
        //录制的最大时长
        <attr name="duration" format="integer">attr>
    declare-styleable>

接着我们在构造方法中获取到这些属性

public class RecordView extends View {

    private int progressMaxValue;
    private final int radius;
    private final int progressWidth;
    private final int progressColor;
    private final int fillColor;
    private final int maxDuration;
    private int progressValue;
    
    public RecordView(Context context) {
        this(context, null);
    }

    public RecordView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RecordView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public RecordView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RecordView, defStyleAttr, defStyleRes);
        radius = typedArray.getDimensionPixelOffset(R.styleable.RecordView_radius, 0);
        progressWidth = typedArray.getDimensionPixelOffset(R.styleable.RecordView_progress_width, PixUtils.dp2px(3));
        progressColor = typedArray.getColor(R.styleable.RecordView_progress_color, Color.RED);
        fillColor = typedArray.getColor(R.styleable.RecordView_fill_color, Color.WHITE);
        maxDuration = typedArray.getInteger(R.styleable.RecordView_duration, 10);
        setMaxDuration(maxDuration);
        typedArray.recycle();
        
    }
}

然后我们定义两个画笔`Paint

  		private final Paint fillPaint;
   		private final Paint progressPaint;

 		fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        fillPaint.setColor(fillColor);
        fillPaint.setStyle(Paint.Style.FILL);

        progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        progressPaint.setColor(progressColor);
        progressPaint.setStyle(Paint.Style.STROKE);
        progressPaint.setStrokeWidth(progressWidth);

然后我们就要区分是拍照还是录视频了,拍照只有下面一个圆形,录制视频还有一个进度条,我们在onDraw方法中实现

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();
        if (isRecording) {

            canvas.drawCircle(width / 2, height / 2, width / 2, fillPaint);

            int left = progressWidth / 2;
            int top = progressWidth / 2;
            int right = width - progressWidth / 2;
            int bottom = height - progressWidth / 2;
            float sweepAngle = (progressValue * 1.0f / progressMaxValue) * 360;
            canvas.drawArc(left, top, right, bottom, -90, sweepAngle, false, progressPaint);
        } else {
            canvas.drawCircle(width / 2, height / 2, radius, fillPaint);
        }
    }

接着我们就是需要监听点击事件和长按事件,这是使用setOnTouchListener,监听按下和抬起的时间来判断

 setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    isRecording = true;
                    startRecordTime = System.currentTimeMillis();
                    handler.sendEmptyMessage(0);
                } else if (event.getAction() == MotionEvent.ACTION_UP) {
                    long now = System.currentTimeMillis();
                    if (now - startRecordTime > ViewConfiguration.getLongPressTimeout()) {
                        finishRecord();
                    }
                    handler.removeCallbacksAndMessages(null);
                    isRecording = false;
                    startRecordTime = 0;
                    progressValue = 0;
                    postInvalidate();
                }
                return false;
            }
        });


  Handler handler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                progressValue++;
                postInvalidate();
                if (progressValue <= progressMaxValue) {
                    sendEmptyMessageDelayed(0, PROGRESS_INTERVAL);
                } else {
                    finishRecord();
                }
            }
        };

我们这里是在录制的时候只要没录制完,每隔100毫秒重新刷新下进度条
最后我们再通过接口的形式把事件传递出去

 public interface onRecordListener {
        void onClick();

        void onLongClick();

        void onFinish();
    }

`

你可能感兴趣的:(Jetpack)