美文网首页
Android实现微信拍照按钮

Android实现微信拍照按钮

作者: 不会弹钢琴de大叔 | 来源:发表于2023-08-07 15:40 被阅读0次

由于项目需要,做了一个自定义View实现了点击拍照,长按录像的功能,有相应的回调事件,见如下代码:

public class CircleButtonView extends View {
    private static final int WHAT_LONG_CLICK = 1;
    private static final int WHAT_RECORD_VIDEO = 2;
    private Paint mPaint;
    private Paint mBarPaint;
    private Paint mTextPaint;
    private int mWidth;
    private float mStrokeWidth;
    private long mStartTime;
    private boolean isRecording, isPressed;
    private float mCurrentProgress;
    private final int updateTime = 50;
    private final int longClickTime = 150;
    private int curTime;
    private OnClickListener clickListener;
    private OnLongClickListener longClickListener;
    private Bitmap mSeatBitmap;
    private String mText;

    public CircleButtonView(Context context) {
        super(context);
        init();
    }

    public CircleButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

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

    private void init() {
        //初始画笔抗锯齿、颜色
        mStrokeWidth = dip2px(10);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mTextPaint = new Paint();
        mTextPaint.setTextSize(24);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setColor(ContextCompat.getColor(getContext(), R.color.gwm_color_main_text));
        mBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBarPaint.setColor(Color.parseColor("#6ABF66"));
        mBarPaint.setStrokeWidth(mStrokeWidth);
        mBarPaint.setStyle(Paint.Style.STROKE);
        mBarPaint.setAntiAlias(true);
        mSeatBitmap = getBitmapFromDrawable(R.drawable.icon_temp_zuoyi);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        mWidth = getMeasuredWidth();
    }

    @Override
    protected void onDraw(final Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mSeatBitmap, 0, 0, mPaint);
        if (isRecording) {
            drawProgress(canvas);
        }
        canvas.drawText(mText, mWidth / 2f, mWidth + dip2px(30), mTextPaint);
    }

    /**
     * 绘制圆形进度
     *
     * @param canvas
     */
    private void drawProgress(Canvas canvas) {
        RectF oval = new RectF(0 + mStrokeWidth / 2f, 0 + mStrokeWidth / 2f,
                mWidth - mStrokeWidth / 2f, mWidth - mStrokeWidth / 2f);
        canvas.drawArc(oval, -90, mCurrentProgress, false, mBarPaint);
    }

    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //长按事件触发
            if (msg.what == WHAT_LONG_CLICK) {
                curTime = longClickTime;
                mCurrentProgress = 0;
                isRecording = true;
                invalidate();
                sendCircle();
            } else if (msg.what == WHAT_RECORD_VIDEO) {
                int mRecordTime = 1000;
                if (mRecordTime > curTime) {
                    curTime += updateTime;
                    mCurrentProgress = (float) 360 / mRecordTime * curTime;
                    invalidate();
                    sendCircle();
                } else {
                    if (isPressed) {
                        reset();
                        LogUtils.logi("longClick view");
                        if (longClickListener != null) {
                            longClickListener.onLongClick(CircleButtonView.this);
                        }
                    }
                }
            }
        }
    };

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                LogUtils.logi("onTouchEvent click: start");
                isPressed = true;
                mStartTime = System.currentTimeMillis();
                Message mMessage = Message.obtain();
                mMessage.what = WHAT_LONG_CLICK;
                mHandler.sendMessageDelayed(mMessage, longClickTime);
                break;
            case MotionEvent.ACTION_UP:
                reset();
                long mEndTime = System.currentTimeMillis();
                if (mEndTime - mStartTime < longClickTime) {
                    LogUtils.logi("click view");
                    if (clickListener != null) {
                        clickListener.onClick(this);
                    }
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                reset();
                break;
            default:
                break;
        }
        return true;
    }

    public void setClickListener(OnClickListener clickListener) {
        this.clickListener = clickListener;
    }

    public void setLongClickListener(OnLongClickListener longClickListener) {
        this.longClickListener = longClickListener;
    }

    public void setViewText(String text) {
        mText = text;
    }

    private void reset() {
        isPressed = false;
        isRecording = false;
        mHandler.removeMessages(WHAT_LONG_CLICK);
        mHandler.removeMessages(WHAT_RECORD_VIDEO);
        mCurrentProgress = 0;
        invalidate();
    }

    private void sendCircle() {
        mHandler.sendEmptyMessageDelayed(WHAT_RECORD_VIDEO, updateTime);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mHandler.removeCallbacksAndMessages(null);
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    private int dip2px(float dpValue) {
        final float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    private Bitmap getBitmapFromDrawable(@DrawableRes int drawableId) {
        Drawable drawable = ContextCompat.getDrawable(getContext(), drawableId);
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof VectorDrawable || drawable instanceof VectorDrawableCompat) {
            Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        } else {
            throw new IllegalArgumentException("unsupported drawable type");
        }
    }
}

相关文章

网友评论

      本文标题:Android实现微信拍照按钮

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