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 ...
随机推荐
- Android获取屏幕宽和高
android获取屏幕的高度和宽度用到WindowManager这个类,两种方法: 1.WindowManager wm = (WindowManager) getContext() ...
- NPOI简介
NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. (一)传统操作Excel遇到的问题: 1.如果是.NET,需要在服务器端 ...
- linux永久更改eth0的ip地址后仍然ping不通过
编辑文件/etc/sysconfig/network-scripts/ifcfg-eth0 引用:DEVICE=eth0 //设备名称,不要修改 BOOTPROTO=static //不要修改 BRO ...
- Hash_P1026毒药?解药?
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> ...
- SPOJ GSS3 Can you answer these queries III
Time Limit: 330MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Description You are g ...
- [NOIP2015] 提高组 洛谷P2668 斗地主
题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...
- UDP打洞、P2P组网方式研究
catalogue . NAT概念 . P2P概念 . UDP打洞 . P2P DEMO . ZeroNet P2P 1. NAT概念 在STUN协议中,根据内部终端的地址(LocalIP:Local ...
- 数据结构作业——order(二叉树遍历)
order Description 给出一棵二叉树的中序遍历和每个节点的父节点,求这棵二叉树的先序和后 序遍历. Input 输入第一行为一个正整数 n 表示二叉树的节点数目, 节点编号从 1 到 n ...
- JavaWeb---总结(十七)JSP中的九个内置对象
一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...
- BZOJ4415: [Shoi2013]发牌
显然可以线段树或树状数组上二分. 然而直接写splay在bzoj上并不会T. 然而发这题的目的只是因为我又忘了return了啊啊啊啊(TдT) 内心十分崩溃.关键是在本地还能过. #include&l ...