实现磁贴的效果的一种方法
由于今年win8的那种磁贴效果比较流行,所以我们的项目决定使用这种磁贴。经过在网上的搜索查询,有一位大神的效果看起来比较炫酷,所以特下载下来进行了钻研,在基本弄懂了实现方法后,特在此总结,以备以后的使用。
有以下几点需要说明:
1>磁贴的图片是自己用ps根据手机的像素和hpi扣出来的,是一种纯色块。
2>磁贴的缩放特效是Matrix实现的。
3>磁贴的旋转特效是Camera和Matrix实现的。(Camera是Graphics包里边的类,请注意)
4>磁贴是自定义的ImageView,需要在XML中用自定义的。
5>getHeight()之类的方法是得到ImageView的大小,即当前色块的大小。
6>event.getX()之类的方法的父框架是当前色块,得到的x和y坐标永远在当前色块,(0,0)在色块的左上角。
7>按下屏幕是缩放或者旋转,松开是恢复原状态。
7>其余需要注意的地方在代码中或者贴出代码后在说。
1.先说明一下缩放特效的实现方法。
@Overridepublic boolean onTouchEvent(MotionEvent event) {super.onTouchEvent(event);switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN:float X = event.getX(); //得到的是相对于图片来说的x y (0,0)为左上角float Y = event.getY();RolateX = Width / 2 - X;RolateY = Height / 2 - Y;XbigY = Math.abs(RolateX) > Math.abs(RolateY) ? true : false;isScale = X > Width / 3 && X < Width * 2 / 3 && Y > Height / 3&& Y < Height * 2 / 3; //分成9塊,在中間的一塊if (isScale){handler.sendEmptyMessage(Constant.First_Scale);} else{rolateHandler.sendEmptyMessage(Constant.First_Rotate);}break;case MotionEvent.ACTION_UP:if (isScale) {handler.sendEmptyMessage(Constant.Recover_Scale);} else {rolateHandler.sendEmptyMessage(Constant.Recover_Rotate);}break;}return true;}
做一下说明:
1>这个是把键盘分成9块,如果按的是中间的那一块,则是缩放,其余的八块根据x和y的大小则是不同的旋转效果。
2>开两个Handler线程,分别处理旋转和缩放。
private synchronized void BeginScale(Matrix matrix, float scale) {matrix.postScale(scale, scale, halfWidth, halfHeight); //前俩参数为x y轴的拉伸变化,大于1为拉伸。 后俩参数制定缩放的中心setImageMatrix(matrix);}
如注释所示,伸缩特效的实现方法比较简单,前两个参数是x和y轴的拉伸变化,大于1是拉伸,小于1的伸缩,后两个参数指定中心点,这里的中心点是色块的中点。
private Handler handler = new Handler() {private Matrix matrix = new Matrix();private float s;int count = 0;@Overridepublic void handleMessage(Message msg){super.handleMessage(msg);matrix.set(getImageMatrix());switch (msg.what) {case Constant.First_Scale:if(!isFinish) //防止还未恢复成原状客户又点击{return;}else{isFinish = false;count = 0;s = (float) Math.sqrt(Math.sqrt(minScale));BeginScale(matrix, s);handler.sendEmptyMessage(Constant.Middle_Scale);}break;case Constant.Middle_Scale:BeginScale(matrix, s); if (count < MaxScaleCount) { //设置次数是在每次缩放的基础上,继续缩放,形成缩放比较深的效果handler.sendEmptyMessage(Constant.Middle_Scale);} else{isFinish = true;}count++;break;case Constant.Recover_Scale:if (!isFinish){handler.sendEmptyMessage(Constant.Recover_Scale);} else {isFinish = false;count = 0;s = (float) Math.sqrt(Math.sqrt(1.0f / minScale)); //经过几次的拉伸变回原来的大小BeginScale(matrix, s);handler.sendEmptyMessage(Constant.Middle_Scale);}break;}}};
这是处理伸缩特效的线程,如注释,有几点需要说明:
1>为了防止客户连续点击磁贴,设置一个标志位isFinish,如果磁贴伸缩并且恢复成原形状,则这个标志位为true,否则为false,在第一次点击中,可以很好的防止磁贴变形。
2>为了形成比较深的缩放效果,设置了多层缩放,即在第一次点击以后,发消息给中间缩放,在第一次的基础上,继续进行缩放。
3>当用户松开屏幕后,发消息给处理恢复磁贴的部分,在最后的缩放过程一步一步按照缩放的过程进行恢复。
下面贴出旋转特效的代码。
private synchronized void BeginRolate(Matrix matrix, float rolateX, float rolateY){camera.save();camera.rotateX(RolateY > 0 ? rolateY : -rolateY); // 旋转的角度camera.rotateY(RolateX < 0 ? rolateX : -rolateX);camera.getMatrix(matrix);camera.restore();if (RolateX > 0 && rolateX != 0) //第一个参数大于零表示向右,小于向左。第二个参数大于零向下,小于零向上 首先将坐标平移到该点,在进行旋转{ matrix.preTranslate(-Width, -halfHeight); //向左下压matrix.postTranslate(Width, halfHeight);} else if (RolateY > 0 && rolateY != 0) //向上边压{ matrix.preTranslate(-halfWidth, -Height);matrix.postTranslate(halfWidth, Height);} else if (RolateX < 0 && rolateX != 0) //向右压{matrix.preTranslate(-0, -halfHeight);matrix.postTranslate(0, halfHeight);} else if (RolateY < 0 && rolateY != 0) //向下压{matrix.preTranslate(-halfWidth, -0);matrix.postTranslate(halfWidth, 0);}setImageMatrix(matrix);}
有几点需要说明:
1>旋转特效是Camera负责旋转,而Matrix负责平移,在此处是将旋转的中心点平移到合适的位置。
2>preTranslate(x,y)和postTranslate(x,y)负责平移,如果x>0,表示向右平移,x<0表示向左平移。y>0向下平移,y<0向上平移。
3>preTranslate(x,y)相当于右乘矩阵,即在旋转之前进行的平移。
4>postTranslate(x,y)相当于左乘矩阵,即在旋转之后进行的平移。
5>Camera的坐标系是左手坐标系,可以参考一下上一篇博客。
6>根据不同的条件判断是左压,右压,上压还是下压。
下面贴出处理旋转的线程。
private Handler rolateHandler = new Handler(){private Matrix matrix = new Matrix();private float count =0;@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);matrix.set(getImageMatrix());switch (msg.what) {case Constant.First_Rotate:count = 0;BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));rolateHandler.sendEmptyMessage(Constant.Middle_Rotate);break;case Constant.Middle_Rotate:BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));if (count < rotateDegree) {rolateHandler.sendEmptyMessage(Constant.Middle_Rotate);} else {isFinish = true;}count+=2;break;case Constant.Middle_Recover_Rotate:BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));if (count > 0) {rolateHandler.sendEmptyMessage(Constant.Middle_Recover_Rotate);} else {isFinish = true;}count-=2;break;case Constant.Recover_Rotate:count = rotateDegree;BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));rolateHandler.sendEmptyMessage(Constant.Middle_Recover_Rotate);break;}}};
这里需要说明几点:
1>count表明的是旋转角度,作用和缩放一样,是为了形成比较深的效果。
2>恢复的时候也是相当于一帧一帧的恢复,从10逐渐变为0。
参考网友的总结,做一下总体总结,如下。
- Camera的rotate()相关方法是指定某一维度上旋转指定的角度。
- Matrix的rotate()相关方法实现的效果是顺时针旋转指定的角度;与Camera指定Z轴旋转效果相同,但方向相反。
- Camera的translate()方法根据某一维度上视点的位移实现图像的缩放,与Matrix的scale()相关方法作用效果相似,只是Matrix的scale()相关方法是直接指定缩放比例。
- Camera不支持倾斜操作,Matrix可以直接实现倾斜操作。
转载于:https://www.cnblogs.com/lzya/p/4913019.html
实现磁贴的效果的一种方法相关推荐
- 视图实现圆角效果的三种方法及比较
本篇文章主要介绍了"视图实现圆角效果的三种方法及比较",主要涉及到视图实现圆角效果的三种方法及比较方面的内容,对于视图实现圆角效果的三种方法及比较感兴趣的同学可以参考一下. 方法一 ...
- iOS 视图实现圆角效果的三种方法及比较
通过代码,至少有三种方法可以为视图加上圆角效果.附例子: https://github.com/weipin/RoundedCorner 方法一.layer.cornerRadius 第一种方法最简单 ...
- 前端页面实现倒计时效果的几种方法
倒计时的效果在网站或其他平台剪得很多了吧,今天就让我们来看看实现它的几种方法吧! 一 --15分钟倒计时 <html> <head> <meta charset=&quo ...
- CSS实现背景图片透明文字不透明效果的两种方法
网页设计中经常要在背景图上放一些文字介绍,这就需要背景图片能有透明效果以便突出显示文字信息,经多方查阅,终于找到了2种有趣的方法. 1.在文字层添加rgba样式实现半透明效果 方法: 背景图片层添加样 ...
- html 图片透明字不透明,CSS实现背景图片透明,文字不透明效果的两种方法
项目中经常会用到背景图上放一些文字介绍,这里介绍两种技术来实现背景图片透明,文字不透明效果,记录一下,方便日后学习. 1.毛玻璃效果:背景图 + 伪类 + flite:blur(3px) .demo1 ...
- Android设置透明效果的三种方法(转)
1.使用Android系统自带的透明效果资源 <Button android:background="@android:color/transparent"/> ...
- windows之实现3D立体效果的三种方法
第一种:快捷键:win+tab 另外一种:cmd输入rundll32.exe dwmapi #105 第三种:使用软件bumptop
- 模型评价 - 判断数据模型拟合效果的三种方法
数据建模的目的就是获得从自变量映射到因变量的函数,在建模的探索过程中,不同的方式总会得出不同的函数模型,而这些函数大多是由一些参数构成的,比如 y = f( x; w0, w1, w2, w3, .. ...
- 【Android进阶学习】设置透明效果的三种方法
1.使用Android系统自带的透明效果资源 <android:backgroundandroid:background="@android:color/transparent&quo ...
最新文章
- Java堆和栈的区别
- 工作145:vue里面取消console和debugger
- SQL视图学习(入门概念理解)
- Teamcenter 开发中的一些问题
- Linux umask and chmod
- js基础-6-作用域、执行流程、this指向
- python处理异常的方式_Python报错出现异常的介绍,及其处理方式
- WebRTC源码架构浅析
- 利用jackson-dataformat-xml包中的XmlMapper类将xml解析成实体类对象
- 信息隐藏基础算法——LSB算法(python实现)
- 在线工具网,程序员必备小网址
- 【Mathematica】 函数的积分
- Android安卓原生接支付宝SDK支付客户端
- 算法leetcode|剑指 Offer 27. 二叉树的镜像|226. 翻转二叉树(rust很强)
- 手机支付:合作之路才是正途
- B. Nezzar and Lucky Number
- 反欺诈概念库-信用卡反欺诈管理
- 雨中的尾巴(线段树合并+树上差分)
- 有、无线电的信号传输
- ios越狱python插件_基于Theos越狱开发
热门文章
- python解释器的安装步骤-Python本地及虚拟解释器配置过程解析
- 以python入门教程新世界-Python打开新世界的大门-入门篇1
- python3.6.2安装教程-Linux下升级安装Python-3.6.2版本
- python 自动化-五大自动化测试的Python框架
- python开发桌面软件-python适合开发桌面软件吗?
- python自带的shell是什么-python shell是什么东西?
- python打开是什么样的-Python程序的执行过程是什么样的?
- 对于python来说、一个模块就是一个文件-python常用模块
- python怎么导入时间-python初步学习-import和datetime模块
- python是c语言写的吗-学习python还是c语言?