android控件库(2)-仿Google Camera 的对焦效果

时间:2023-03-09 13:23:13
android控件库(2)-仿Google Camera 的对焦效果

一直很喜欢Google Camera的自动对焦效果,今日闲来无事,自己做了个:

android控件库(2)-仿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>

代码很简单,注释已经写得很详细了,相信大家都能看得懂。

最终效果:

android控件库(2)-仿Google Camera 的对焦效果