一直很喜欢Google Camera的自动对焦效果,今日闲来无事,自己做了个:
废话不多说,代码才是王道:
package com.example.test.view; import com.example.test.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * Focus View * @author xp.chen */ public class FocusView extends View { public FocusView(Context context) { super(context); } public FocusView(Context context, AttributeSet attrs) { super(context, attrs); init(context,attrs); } private Paint mPaint; private void init(Context context, AttributeSet attrs) { // init paint TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.FocusView); int count = typedArray.getIndexCount(); for (int i = 0; i < count; i++) { int id = typedArray.getIndex(i); switch (id) { case R.styleable.FocusView_focusColor: paintColor = typedArray.getColor(id, Color.WHITE); break; case R.styleable.FocusView_focusDefaultRadius: radius = typedArray.getFloat(id, 20); break; case R.styleable.FocusView_focusMaxRadius: maxRadius = typedArray.getFloat(id, 100); break; default: break; } } typedArray.recycle(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(3); mPaint.setColor(paintColor); } // addGestureRecognizer UITapGestureRecognizer @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // UIGestureRecognizerStateBegan if (!isStart) { centerX = event.getX(); centerY = event.getY(); // 重量选框参数 isStart = true; isNeedDismiss = false; paintAlpha = 255; mPaint.setAlpha(paintAlpha); radius = 20; invalidate(); mHandler.obtainMessage(0).sendToTarget(); } break; case MotionEvent.ACTION_MOVE: // UIGestureRecognizerStateChange break; case MotionEvent.ACTION_UP: // UIGestureRecognizerStateEnd break; default: break; } return super.onTouchEvent(event); } private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: // update size radius += 5; if (radius >= maxRadius) { // 若将要绘制的尺寸大于约束的最大尺寸,则将该尺寸还原 radius -= 5; mHandler.sendEmptyMessageDelayed(1, 1000); // 使选框停留1s后逐渐消失 } else { mHandler.sendEmptyMessageDelayed(0, (long)(200f/radius)); invalidate(); // setNeedDisplay } break; case 1: // update alpha paintAlpha -= 20; // 当选框达到最大后,就不断改变其透明度,直至透明度为0,本次绘制过程结束 if (paintAlpha <=0) { isNeedDismiss = true; invalidate(); isStart = false; } else { mPaint.setAlpha(paintAlpha); invalidate(); mHandler.sendEmptyMessageDelayed(1,15); } break; default: break; } } }; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // CGSize // setMeasuredDimension(measuredWidth, measuredHeight); } private float centerX; // 焦点中心点X private float centerY; // 焦点中心点Y private float radius = 20; // 焦点选框的最小半径 private float maxRadius = 100; // 焦点选框的最大半径 private int paintAlpha = 255; // 焦点选框的最大透明度 private int paintColor = Color.WHITE; /** * 设置焦点选框的初始半径 * @param radius */ public void setFocusCircleRadius(float radius) { this.radius = radius; } /** * 设置焦点选框的最大半径 * @param radius */ public void setFocusCircleMaxRadius(float radius) { this.maxRadius = radius; } /** * 设置焦点选框的颜色 * @param color */ public void setFocusCircleColor(int color) { this.paintColor = color; mPaint.setColor(color); } /** * 焦点选框是否需要消失 */ private boolean isNeedDismiss = true; /** * 是否已经开始绘制的标志位。如果已经开始绘制,则拒绝下一次点击绘制请求 */ private boolean isStart = false; // drawRect @Override protected void onDraw(Canvas canvas) { if (!isNeedDismiss) { // 若绘制过程结束,则清除焦点框 canvas.drawCircle(centerX, centerY, radius, mPaint); } } }
attrs.xml
<declare-styleable name="FocusView"> <attr name="focusDefaultRadius" format="float"/> <attr name="focusMaxRadius" format="float"/> <attr name="focusColor" format="color"/> </declare-styleable>
activity.main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.example.test" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000" > <com.example.test.view.FocusView android:layout_width="wrap_content" android:layout_height="wrap_content" app:focusColor = "#fff" app:focusMaxRadius = "100" /> </RelativeLayout>
代码很简单,注释已经写得很详细了,相信大家都能看得懂。
最终效果: