
自己写了一个另外版本,感觉不是很好,借鉴了一下老哥的代码,优化了一下,感谢老哥,尾部附链接。
简单粗暴,没有太多扩展,如果需要可以写一些扩展,我只是实现出来懒得扩展了,因为就是自己写着玩的,没有什么需求。
话不多说,直接上代码:
public class VIDeoTakebutton extends VIEw { private static final String TAG = "VIDeoTakebutton"; /** * 外边框半透明圆的画笔 */ private Paint mPaint0; /** * 内部圆的画笔 */ private Paint mPaint1; /** * 进度条的画笔 */ private Paint mPaint2; /** * 进度条动画 */ private ValueAnimator mProgressAni; /** * 最大拍摄时间,视频只能拍这么久 */ private int mMaxTime = 15; /** * 视频的最小拍摄时间,小于这个时间都按拍照处理 */ private float mMinTime = 0.6F; /** * 外边框的半透明圆的尺寸 */ private float bigCircleRadius = 0; /** * 外边框半透明圆的动画开始尺寸 */ private float bigCircleStarTradius = 0; /** * 外边框半透明圆的动画结束尺寸 */ private float bigCircleEndRadius = 0; /** * 内部圆的尺寸 */ private float smallCircleRadius = 0; /** * 内部圆的动画开始尺寸 */ private float smallCircleStarTradius = 0; /** * 内部圆的动画结束尺寸 */ private float smallCircleEndRadius = 40; /** * 拍摄视频的进度条 */ private float progress = 0; /** * 开始点击的消息码 */ private static final int START_CliCK = 0x001; /** * 长按事件的消息码 */ private static final int LONG_CliCK = 0x002; /** * 按钮按下时间 */ private long mStartTime = 0L; /** * 按钮抬起时间 */ private long mEndTime = 0L; /** * 长按最短时间 单位毫秒 */ public long LONG_CliCK_MIN_TIME = 800L; public VIDeoTakebutton(Context context) { super(context); init(context); } public VIDeoTakebutton(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context); } public VIDeoTakebutton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private voID init(Context context) { mPaint0 = new Paint(); mPaint0.setcolor(color.WHITE); mPaint0.setAlpha(150); mPaint1 = new Paint(); mPaint1.setcolor(color.WHITE); mPaint1.setAlpha(255); mPaint2 = new Paint(); mPaint2.setcolor(color.GREEN); mPaint2.setAlpha(255); //进度条的属性动画 mProgressAni = ValueAnimator.offloat(0, 360f); mProgressAni.setDuration(mMaxTime * 1000); } private VIEwHandler vIEwHandler = new VIEwHandler(this); static class VIEwHandler extends androID.os.Handler { private WeakReference<VIDeoTakebutton> weakReference = null; public VIEwHandler(VIDeoTakebutton vIDeoTakebutton) { weakReference = new WeakReference<>(vIDeoTakebutton); } @OverrIDe public voID handleMessage(@NonNull Message msg) { super.handleMessage(msg); if (weakReference == null || weakReference.get() == null) return; final VIDeoTakebutton vIDeoTakebutton = weakReference.get(); switch (msg.what) { case VIDeoTakebutton.START_CliCK: vIDeoTakebutton.startAnimationClick(); break; case VIDeoTakebutton.LONG_CliCK: if (vIDeoTakebutton.callBack != null) { vIDeoTakebutton.callBack.takeVIDeoStart(); } break; } } } @OverrIDe public voID draw(Canvas canvas) { super.draw(canvas); float x = getWIDth(); float y = getHeight(); float pointX = x / 2; float pointY = y / 2; bigCircleStarTradius = x / 2 - x / 15; bigCircleEndRadius = x / 2; smallCircleStarTradius = x * 2 / 5 - x / 15; smallCircleEndRadius = (x * 2 / 5 - x / 15) / 2; if (isRecording) { canvas.drawCircle(pointX, pointY, bigCircleRadius, mPaint0); canvas.drawCircle(pointX, pointY, smallCircleRadius, mPaint1); //使用离屏绘制 int layerID = canvas.saveLayer(0, 0, getWIDth(), getHeight(), mPaint2, Canvas.ALL_SAVE_FLAG); canvas.drawArc(x / 15, x / 15, x - x / 15, x - x / 15, 270, progress, true, mPaint2); mPaint2.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)); canvas.drawArc(0, 0, x, x, 270, progress, true, mPaint2); mPaint2.setXfermode(null); canvas.restoretoCount(layerID); } else { bigCircleRadius = bigCircleStarTradius; canvas.drawCircle(pointX, pointY, bigCircleRadius, mPaint0); smallCircleRadius = smallCircleStarTradius; canvas.drawCircle(pointX, pointY, smallCircleRadius, mPaint1); } } private voID startAnimationClick() { ValueAnimator smallCircle = ValueAnimator.offloat(smallCircleStarTradius, smallCircleEndRadius); smallCircle.setDuration(300); smallCircle.addUpdateListener(animation -> { smallCircleRadius = (float) animation.getAnimatedValue(); invalIDate(); }); ValueAnimator bigCircle = ValueAnimator.offloat(bigCircleStarTradius, bigCircleEndRadius); bigCircle.setDuration(300); bigCircle.addUpdateListener(animation -> { if (isRecording) { bigCircleRadius = (float) animation.getAnimatedValue(); invalIDate(); } }); smallCircle.start(); bigCircle.start(); smallCircle.addListener(new Animator.AnimatorListener() { @OverrIDe public voID onAnimationStart(Animator animator) { } @OverrIDe public voID onAnimationEnd(Animator animator) { //开始绘制圆形进度条 if (isRecording) { startAniProgress(); } } @OverrIDe public voID onAnimationCancel(Animator animator) { } @OverrIDe public voID onAnimationRepeat(Animator animator) { } }); } private voID startAniProgress() { if (mProgressAni == null) return; mProgressAni.start(); mProgressAni.addUpdateListener(valueAnimator -> { progress = (float) valueAnimator.getAnimatedValue(); postInvalIDate(); }); mProgressAni.addListener(new AnimatorListenerAdapter() { @OverrIDe public voID onAnimationEnd(Animator animation) { isRecording = false; progress = 0; postInvalIDate(); } }); } private boolean isRecording = false; @Suppresslint("ClickableVIEwAccessibility") @OverrIDe public boolean ontouchEvent(MotionEvent event) { super.ontouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: isRecording = true; mStartTime = System.currentTimeMillis(); vIEwHandler.sendEmptyMessage(START_CliCK); vIEwHandler.sendEmptyMessageDelayed(LONG_CliCK, LONG_CliCK_MIN_TIME); break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: isRecording = false; mEndTime = System.currentTimeMillis(); if (mEndTime - mStartTime < LONG_CliCK_MIN_TIME) { if (vIEwHandler.hasMessages(LONG_CliCK)) { vIEwHandler.removeMessages(LONG_CliCK); } if (callBack != null) { callBack.takePhoto(); } } else { if (mProgressAni != null && progress / 10 < mMinTime) { if (callBack != null) { callBack.takePhoto(); } } else { if (callBack != null) { callBack.takeVIDeoEnd(); } } } if (mProgressAni != null) { mProgressAni.cancel(); } break; } return true; } interface CallBack { voID takePhoto(); voID takeVIDeoStart(); voID takeVIDeoEnd(); } private CallBack callBack; public voID setCallBack(CallBack callBack) { this.callBack = callBack; } @OverrIDe protected voID onMeasure(int wIDthMeasureSpec, int heightmeasureSpec) { super.onMeasure(wIDthMeasureSpec, heightmeasureSpec); int screenWIDth = getScreenWIDth(); int wIDth = screenWIDth * 23 / 100; setMeasuredDimension(wIDth, wIDth); } /** * 获取屏幕宽度 * * @return */ private int getScreenWIDth() { WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); displayMetrics displayMetrics = new displayMetrics(); windowManager.getDefaultdisplay().getMetrics(displayMetrics); return displayMetrics.wIDthPixels; }}
感谢老哥: 总结
以上是内存溢出为你收集整理的Android 仿微信拍摄按钮全部内容,希望文章能够帮你解决Android 仿微信拍摄按钮所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)