您好,登錄后才能下訂單哦!
Android仿微信相機的拍照按鈕單擊拍照,長按錄視頻。先上效果圖。
項目地址:https://github.com/c786909486/PhotoButton2/tree/v1.0
添加依賴
allprojects { repositories { ... maven { url 'https://jitpack.io' } } } dependencies { compile compile 'com.github.c786909486:PhotoButton2:v1.1' }
長按效果分析
判斷是否為長按,如果是,則擴大外圓,縮小內圓。由于要擴大外圓,所以在繪制常態的外圓時不可將圓的直徑設置為view的寬度或高度。
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); if (isLongClick){ canvas.drawCircle(width/2,height/2, innerRaduis /2.0f, innerRoundPaint); //畫外原環 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); }
然后通過手勢識別判斷單擊、長按、長按抬起。
mDetector = new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapConfirmed(MotionEvent e) { //單擊 isLongClick = false; if (listener != null) { listener.onClick(TakePhotoButton.this); } return super.onSingleTapConfirmed(e); } @Override public void onLongPress(MotionEvent e) { //長按 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_CANCEL: if (isLongClick) { isLongClick = false; postInvalidate(); if (this.listener != null) { this.listener.onLongClickUp(this); } } break; } return true; }
自定義接口對各個狀態進行監聽
public interface OnProgressTouchListener { /** * 單擊 * @param photoButton */ void onClick(TakePhotoButton photoButton); /** * 長按 * @param photoButton */ void onLongClick(TakePhotoButton photoButton); /** * 長按抬起 * @param photoButton */ void onLongClickUp(TakePhotoButton photoButton); void onFinish(); }
最后,給外圓弧添加動畫
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(); //獲取到需要繪制的角度,重新繪制 invalidate(); } }); //這里是時間獲取和賦值 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.onAnimationEnd(animation); clearAnimation(); isLongClick = false; postInvalidate(); if (listener != null) { listener.onFinish(); } } }); }
最后,在activity中給控件設置監聽即可。
buttontake.setOnProgressTouchListener(new TakePhotoButton.OnProgressTouchListener() { @Override public void onClick(TakePhotoButton photoButton) { Toast.makeText(MainActivity.this,"單機",Toast.LENGTH_SHORT).show(); } @Override public void onLongClick(TakePhotoButton photoButton) { Toast.makeText(MainActivity.this,"長按",Toast.LENGTH_SHORT).show(); buttontake.start(); } @Override public void onLongClickUp(TakePhotoButton photoButton) { onFinish(); } @Override public void onFinish() { Toast.makeText(MainActivity.this,"錄制結束",Toast.LENGTH_SHORT).show(); } });
button.s
下面貼上完整的代碼
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;//外圓環寬度 private int outCircleColor;//外圓顏色 private int innerCircleColor;//內圓顏色 private int progressColor;//進度條顏色 private Paint outRoundPaint = new Paint(); //外圓畫筆 private Paint mCPaint = new Paint();//進度畫筆 private Paint innerRoundPaint = new Paint(); private float width; //自定義view的寬度 private float height; //自定義view的高度 private float outRaduis; //外圓半徑 private float innerRaduis;//內圓半徑 private GestureDetectorCompat mDetector;//手勢識別 private boolean isLongClick;//是否長按 private float startAngle = -90;//開始角度 private float mmSweepAngleStart = 0f;//起點 private float mmSweepAngleEnd = 360f;//終點 private float mSweepAngle;//掃過的角度 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) { //單擊 isLongClick = false; if (listener != null) { listener.onClick(TakePhotoButton.this); } return super.onSingleTapConfirmed(e); } @Override public void onLongPress(MotionEvent e) { //長按 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(); //畫外圓 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); //畫內圓 innerRoundPaint.setAntiAlias(true); innerRoundPaint.setColor(innerCircleColor); if (isLongClick){ canvas.drawCircle(width/2,height/2, innerRaduis /2.0f, innerRoundPaint); //畫外原環 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); } } 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(); //獲取到需要繪制的角度,重新繪制 invalidate(); } }); //這里是時間獲取和賦值 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.onAnimationEnd(animation); clearAnimation(); 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; } /** * 進度觸摸監聽 */ public interface OnProgressTouchListener { /** * 單擊 * @param photoButton */ void onClick(TakePhotoButton photoButton); /** * 長按 * @param photoButton */ void onLongClick(TakePhotoButton photoButton); /** * 長按抬起 * @param photoButton */ void onLongClickUp(TakePhotoButton photoButton); void onFinish(); } }
項目地址:https://github.com/c786909486/PhotoButton2/tree/v1.0
總結
以上所述是小編給大家介紹的Android 自定義view仿微信相機單擊拍照長按錄視頻按鈕,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。