android控件库(2)-仿Google Camera 的对焦效果
一直很喜欢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 的对焦效果的更多相关文章
- Android控件GridView之仿支付宝钱包首页带有分割线的GridView九宫格的完美实现
Android控件GridView之仿支付宝钱包首页带有分割线的GridView九宫格的完美实现 2015-03-10 22:38 28419人阅读 评论(17) 收藏 举报 分类: Android ...
- Android控件Gridview实现仿支付宝首页,Fragment底部按钮切换和登录圆形头像
此案例主要讲的是Android控件Gridview(九宫格)完美实现仿支付宝首页,包含添加和删除功能:Fragment底部按钮切换的效果,包含四个模块,登录页面圆形头像等,一个小项目的初始布局. 效果 ...
- Android控件-ViewPager(仿微信引导界面)
什么是ViewPager? ViewPager是安卓3.0之后提供的新特性,继承自ViewGroup,专门用以实现左右滑动切换View的效果. 如果想向下兼容就必须要android-support-v ...
- Android 控件进阶修炼-仿360手机卫士波浪球进度控件
技术:Android+java 概述 像360卫士的波浪球进度的效果,一般最常用的方法就是 画线的方式,先绘sin线或贝塞尔曲线,然后从左到右绘制竖线,然后再裁剪圆区域. 今天我这用图片bitma ...
- android控件库(1)-带删除功能的EditText
DJEditText.java /** * Created by xp.chen on 2016/11/25. */ public class DJEditText extends AppCompat ...
- UIAutomator定位Android控件的方法
UIAutomator各种控件定位的方法. 1. 背景 使用SDK自带的NotePad应用,尝试去获得在NotesList那个Activity里的Menu Options上面的那个Add note菜单 ...
- android控件的属性
android控件的属性 本节描述android空间的位置,内容等相关属性及属性的含义 第一类:属性值为true或false android:layout_centerHrizontal 水平居中 ( ...
- JavaFX的扩展控件库ControlsFX介绍
声明: 本博客文章原创类别的均为个人原创,版权所有.转载请注明出处: http://blog.csdn.net/ml3947,另外本人的个人博客:http://www.wjfxgame.com. ...
- 【转】UIAutomator定位Android控件的方法实践和建议(Appium姊妹篇)
原文地址:http://blog.csdn.net/zhubaitian/article/details/39777951 在本人之前的一篇文章<<Appium基于安卓的各种FindEle ...
随机推荐
- 简进祥-SVN版本控制方案:多分支并行开发,多环境自动部署
两地同时开发一个产品,目前线上有3个环境:测试环境.预发布环境.生产环境.目前系统部署采用jenkins自动化部署工具 用jenkins部署的方案 jenkins 测试环境:配置了各个分支的svn 地 ...
- js-自制轮播插件!
刚接触轮播的时候,感觉这种东西好高端,后来学习了jquery后,发现原来挺简单的,而且实现轮播也有很多形式,我用jquery自制了一个轮播插件,其实我这个说是插件,好像其实就是一个高度抽象的函数而已. ...
- 【BZOJ-2756】奇怪的游戏 最大流 + 分类讨论 + 二分
2756: [SCOI2012]奇怪的游戏 Time Limit: 40 Sec Memory Limit: 128 MBSubmit: 2925 Solved: 792[Submit][Stat ...
- 【poj1085】 Triangle War
http://poj.org/problem?id=1085 (题目链接) 题意 A,B两人玩游戏,在一个大三角形上放火柴,若A放上一根火柴后成功组成一个三角形,那么这个三角形就归属于A,并且A被奖励 ...
- 虚拟机软件bochs编译使用问题
bochs是一款具有调试功能的虚拟机软件,由C++编写,可用于调试操作系统.从ubuntu软件源中下载的很可能没有调试功能,需要先下载源码,可能比编译之后的可执行文件大的多. 编译时有很多选项,可以通 ...
- POJ 1273 Drainage Ditches
Drainage Ditches Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 67387 Accepted: 2603 ...
- nginx ssl证书安装配置
原理图: - 客户端生成一个随机数 random-client,传到服务器端(Say Hello) - 服务器端生成一个随机数 random-server,和着公钥,一起回馈给客户端(I got it ...
- AngularJs 脏值检查及其相关
今天突然就想写写$digest和$apply,这些都是脏值检查的主体内容. 先以普通js来做一个简单的监控例子吧: var div = ducoment.getElementById("my ...
- UVALive 3989Ladies' Choice(稳定婚姻问题)
题目链接 题意:n个男生和女生,先是n行n个数,表示每一个女生对男生的好感值排序,然后是n行n列式每一个男生的好感值排序,输出N行,即每个女生在最好情况下的男生的编号 分析:如果是求女生的最好情况下, ...
- Linux系统信息查看命令大全
系统# uname -a # 查看内核/操作系统/CPU信息# head -n 1 /etc/issue # 查看操作系统版本# cat /proc/cpuinfo # 查看CPU信息# hostna ...