Android Custom View Imitation WeChat Camera Click to shoot the video button

Android imitation WeChat camera’s camera button Click to take pictures, long, record the video. First above the renderings.

Android 自定义view仿微信相机单击拍照长按录视频按钮
Project address: https: //github.com/c786909486/photobutton2/tree/v1.0 Android 自定义view仿微信相机单击拍照长按录视频按钮

Add dependency

AllProjects {repositosities {… maven {url ‘https://jitpack.io’}}} dependencies}}} dependencies}}} dependencies}}} .c786909486: Photobutton2: v1.1 ‘}

Long pressing effect analysis
 Judging whether it is long press, if yes, Then expand the outer circle and shrink the inner circle. Since the outer circle is to be expanded, the circular diameter cannot be set to the width or height of the VIEW when the normal outer circle is plotted.   
OUTROUNDPAINT.Setantialias (TRUE); OUTROUNDPAINT.SETCOLOR (OutcircLick); IF (IslongClick) {Canvas.Scale (1.2F, 1.2F, Width / 2, Height / 2);} canvas.drawcircle (Width / 2, Height / 2, Outraduis, OuTroundPaint); if (IslongClick) {Canvas.Drawcircle (Width / 2, Height / 2, InnerRaduis /2.0f, innerRoundPaint); // Videos original outer ring mCPaint.setAntiAlias ​​(true); mCPaint.setColor (progressColor); mCPaint.setStyle (Paint.Style.STROKE); mCPaint.setStrokeWidth (circleWidth / 2); RectF rectF = new rectF (0 + circleWidth, 0 + circleWidth, width-circleWidth, height-circleWidth); canvas.drawArc (rectF, startAngle, mSweepAngle, false, mCPaint);} else {canvas.drawCircle (width / 2, height / 2 , InnerRaduis, InnerRoundPaint;}
Then click to gesture identification, the length is pressed, and the long press is lifted.

mDetector = new GestureDetectorCompat (context, new GestureDetector.SimpleOnGestureListener () {@Override public boolean onSingleTapConfirmed (MotionEvent e) {// click isLongClick = false; if (listener ! = null) {listener.onClick (TakePhotoButton.this);} return super.onSingleTapConfirmed (e);} @Override public void onLongPress (MotionEvent e) {// Press isLongClick = true; postInvalidate (); if (! listener = null) {listener. onLongClick (TakePhotoButton.this);}}}); mDetector.setIsLongpressEnabled (true); @Override public boolean onTouchEvent (MotionEvent event) {mDetector.onTouchEvent (event); switch (MotionEventCompat.getActionMasked (event)) {case MotionEvent.ACTION_DOWN : islongClick = false; Break; Case MotionEvent.Action_up: Case MotionEvent.Action_Cance: if (islongClick) {islongClick = false; postINValidate (); if (this.listener! = null) {this.listener.onlongClickup (this);}} Break;} return true;}

Custom interface monitors the individual states
   
public interface OnProgressTouchListener {/ ** * click * @param photoButton * / void onClick (TakePhotoButton photoButton); / ** * press * @param photoButton * / void onLongClick (TakePhotoButton Photobutton); / ** * Long press Lift * @Param Photobutton * / Void OnLongClickup (Takephotobutton photobutton); void onfinish ();}

Finally, give the outer circle Arc adding animation
  Public void start () {valueAnimator Animator = valueanimator.offloat (MMSWeepangleEnd); Animator.setInterpolator (New linearinterpolator ()); Animator.addUpdateListener (new ValueAnimator.AnimatorUpdateListener () {@Override public void onAnimationUpdate (ValueAnimator valueAnimator) {mSweepAngle = (float) valueAnimator.getAnimatedValue (); // Get the desired angle to draw, redraw invalidate ();}} ); // this is the time to acquire and assignment ValueAnimator animator1 = ValueAnimator.ofInt (mLoadingTime, 0); animator1.setInterpolator (new LinearInterpolator ()); animator1.addUpdateListener (new ValueAnimator.AnimatorUpdateListener () {@Override public void onAnimationUpdate (ValueAnimator Valueanimator) {int Time = (int) value ();}}); AnimatorSet set = new AnimatorSet (); set.playToGether (Animator, Animator1); set.setduration (MLoadingTime * 1000); set.setInterpolator (new LinearInterpolator ()); set.start (); set.addListener (new AnimatorListenerAdapter () {@Override public void onAnimationEnd (Animator animation) {super.onAnimationEnd (animation); clearAnimation (); isLongClick = false; postInvalidate ( ); if (listener! = NULL) {listener.onfinish ();}}}});}  
Finally, the control is set to the control settings to the control.

buttontake.setOnProgressTouchListener (new TakePhotoButton.OnProgressTouchListener () {@Override public void onClick (TakePhotoButton photoButton) {Toast.makeText (MainActivity.this, “single”, Toast. Length_short) .show ();} @Override public void online (takephotobutton photobutton) {Toast.makeText (MainActivity.this, “long press”, Toast.LENGTH_SHORT) .show (); buttontake.start ();} @Override public void onLongClickUp (TakePhotoButton photoButton) {onFinish ();} @Override public void onFinish ( {TOAST.MAKETEXT (MainActivity.this, “Recording End”, TOAST.LENGTH_SHORT) .SHOW ();}};
   
Button.s
A complete code is attached

Takephotobutton:
Import android.Animation.animator; import android.animation.animatorListeneraDapter; import Android.Animation. AnimatorSet; import android.animation.ValueAnimator; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.support.annotation.Nullable; import android.support.v4.view.GestureDetectorCompat; import android.support.v4.view.MotionEventCompat; import android.util.AttributeSet; import android.view. GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.animation.LinearInterpolator; / ** * Created by CKZ on 2017/8/9 * / public class TakePhotoButton extends View {private float circleWidth. ; // Outer Ring Width Private INT OUTCIRCLECOLOR; // Outline Color Private INT InnerCracolor; // Remote Color Private INT ProgressColor; // Progress Color Private Paint OuTroundPaint = New Paint (); // Exterior Circular Brush Private Paint McPaint = new pressure (); // Progress Brush Private Paint InnerRoundPaint = New Paint (); private float width; // Customize the width private float height; // Customize VIEWHeight private float outRaduis; // outer radius private float innerRaduis; // inner radius private GestureDetectorCompat mDetector; // gesture recognition private boolean isLongClick; // is longer by private float startAngle = -90; // start angle private float mmSweepAngleStart = 0f; // starting private float mmSweepAngleEnd = 360f; // end private float mSweepAngle; // sweep angle private int mLoadingTime; public TakePhotoButton (context context) {this (context, null);} public TakePhotoButton (context context, @Nullable AttributeSet attrs) {this (context, attrs, 0);} public TakePhotoButton (context context, @Nullable AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); init (context, attrs);} private void Init (Context Context, AttributeSet Attrs) {TypeDarray Array = Context. ObtainstyleDattributes (Attrs, R.styleable.TakePhotoButton); outCircleColor = array.getColor (R.styleable.TakePhotoButton_outCircleColor, Color.parseColor ( “# E0E0E0”)); innerCircleColor = array.getColor (R.styleable.TakePhotoButton_innerCircleColor, Color.WHITE); progressColor = array.getColor (R.styleable.TakePhotoButton_readColor, Color.GREEN); mLoadingTime = array.getInteger (R.styleable.TakePhotoButton_maxSeconds, 10); mDetector = new GestureDetectorCompat (context, new GestureDetector.SimpleOnGestureListener () {@Override public boolean onSingleTapConfirmed (MotionEvent E) {// Click IslongClick = false; if (listener! = Null) {listener.onclick (Takephotobutton.this);} Return Super.onusingletApConfirmed (e);} @Override public void onLongPress (MotionEvent e) {// Press isLongClick = true; postInvalidate (); if (listener = null!) {listener.onLongClick (TakePhotoButton.this);}}}); mDetector.setIsLongpressEnabled (true);} private void resetParams () {width = getWidth (); height = getHeight (); circleWidth = width * 0.13f; outRaduis = (float) (Math.min (width, height) /2.4); innerRaduis = outRaduis -circleWidth;} @ override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure (widthMeasureSpec, heightMeasureSpec); int width = MeasureSpec.getSize (widthMeasureSpec); int height = MeasureSpec.getSize (heightMeasureSpec); if (width> height) {setMeasuredDimension ( Height, Height);} Else {setMeasuredDimension (width, width);}} @Override protected void onDraw (Canvas canvas) {resetParams (); // Videos outer outRoundPaint.setAntiAlias ​​(true); outRoundPaint.setColor (outCircleColor); if (isLongClick) { Canvas.scale (1.2F, 1.2F, width / 2, height / 2);} canvas.drawcircle (Width / 2, Height / 2, Outraduis, OuTroundPaint); // Drawn InnerRoundPaint.setantialias (TRUE); InnerRoundPaint .setColor (innerCircleColor); if (isLongClick) {canvas.drawCircle (width / 2, height / 2, innerRaduis /2.0f, innerRoundPaint); // Videos original outer ring mCPaint.setAntiAlias ​​(true); mCPaint.setColor (progressColor) McPaint.setStyle (Paint.Style.Stroke); mcPaint.setstrokewidth (CircleWidth / 2); RectF Rectf = New Rectf (0 + CircleWidth, 0 + Circlewidt)h, width-circleWidth, height-circleWidth); canvas.drawArc (rectF, startAngle, mSweepAngle, false, mCPaint);} else {canvas.drawCircle (width / 2, height / 2, innerRaduis, innerRoundPaint);}} public void start () {valueAnimator animator = ValueAnimator.ofFloat (mmSweepAngleStart, mmSweepAngleEnd); animator.setInterpolator (new LinearInterpolator ()); animator.addUpdateListener (new ValueAnimator.AnimatorUpdateListener () {@Override public void onAnimationUpdate (valueAnimator valueAnimator) {mSweepAngle = ( FLOAT) Valueanimator.GetanImatedValue (); // Get angle you need to draw, redraw information ();}}); // This is the time acquisition and assignment valueanimator Animator1 = valueanimator.ofint (MLoadingTime, 0); Animator1.setInterpolator NEW linearinterpolator ());animator1.addUpdateListener (new ValueAnimator.AnimatorUpdateListener () {@Override public void onAnimationUpdate (ValueAnimator valueAnimator) {int time = (int) valueAnimator.getAnimatedValue ();}}); AnimatorSet set = new AnimatorSet (); set.playTogether (animator , animator1); set.setDuration (mLoadingTime * 1000); set.setInterpolator (new LinearInterpolator ()); set.start (); set.addListener (new AnimatorListenerAdapter () {@Override public void onAnimationEnd (Animator animation) {super. ONAMATIONEND (Animation); lyaNiMation (); islongClick = false; postInvalidate (); if (listener! = null) {listener.onfinish ();}}}});} @Override public boolean ONTOUchEvent (MotionEvent event) {mDetector.onTouchEvent (event); switch (MotionEventCompat.getActionMasked (event)) {case MotionEvent.ACTION_DOWN: isLongClick = false; break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (isLongClick) {isLongClick = false; postInvalidate (); if (this.listener = null!) {this.listener.onLongClickUp (this);}} break;} return true;} private OnProgressTouchListener listener; public void setOnProgressTouchListener (OnProgressTouchListener listener) {this.listener = listener;} / ** * progress touch monitor * / public interface onprogressTouchListener {/ ** * Click * @Param Photobutton * / Void OnclickTakePhotoButton photoButton); / ** * Press * @param photoButton * / void onLongClick (TakePhotoButton photoButton); / ** * Press lift * @param photoButton * / void onLongClickUp (TakePhotoButton photoButton); void onFinish ();} }
   Project Address: https: //github.com/c786909486/photobutton2/tree/v1.0 
Summary

The above is the Android custom virtual customized View imitation WeChat camera, which is introduced to you, I hope to help everyone. If you have any questions, please leave a message, Xiaobian Will reply to everyone in time!
                    
© Copyright Notice
THE END
Just support it if you like
like0
share
comment Grab the couch

Please log in to comment