surfaceView的学习之旅

最近公司出了一个新需求,需求中需要转动转盘手动选择目标,gitHub上转盘资源很多,但是需求就是转动一个图片(类似于背景图片)来选择上面的内容
拿到这个需求时候首先想的是自定义view然后再onTouchEvent监听旋转的角度然后使用旋转动画进行旋转,但是在开发中这个效果并没有想象的那么好,在MotionEvent.ACTION_MOVE:做监听的时候感觉一步一卡,一方面设置旋转所用时间导致,另一方面在如果手指一直在屏幕上移动就会一直调用动画,上一个动画还没结束又接着进行下一个动画导致内存消耗更多,因此并不是最佳的方案
既然自定义view效果不是很好,那就试试surfaceView,这个可是受到程序员青奈的view,他的好处就不多说了,开启一个线程用于绘制图片,效果非常流畅,不过问题来了,使用surfaceView会遇到加载view会出现短暂的黑屏效果,只要用过的人应该都知道吧,原因就是在加载surfaceView之后就会卸载掉,来降低内存开销,这个时候同时也清楚画布的颜色默认是黑色(这也是通常我们看到黑色的原因所在吧)解决的办法就会在surfaceCreated方法中绘制一个背景(可以用一个boolean来控制绘画次数)。这个问题解决后又遇到另外一个问题就会当surfaceview的宿主activity失去焦点然后又获得焦点时候surfaceView又消失了,但是在surfaceCreated绘画的背景还在,消失的仅仅是在开启子线程绘画的消失,恍然发现当宿主生命周期发生改变,对应的view也会发生改变(突然想到上次做的条形图,activity失去焦点等下次再获得焦点时,条形图最高点的数字没了,原因是自定义view又执行onDraw方法,但是之前的全局变量没发生改变导致最大值没了,了解问题所在修改起来就方便多了)解决此问题的方法就是在surfaceCreated通知子线程绘画图形,这样就解决了
图形的绘画算是解决了,现在就是转动和对不同位置进行监听
旋转:就使用Matrix.postRotate方法,只有得到旋转角度和旋转中心,旋转中心根据需求来,角度就在MotionEvent.ACTION_MOVE方法里获取手指在屏幕上滑动的坐标然后使用Math提供的函数(你会惊奇的发现Math函数并不是用java写的而是调用native方法,至于为什么不用java写的就不清楚了)获得旋转角度
位置监听:这个简单,记录初始位置,和旋转角度,加起来就行(不过有正有负,哈哈)
算是完成需求,但是他们觉得每次转动后转盘每次停留在某个位置更好(需求改变你也得跟着变,这就是苦逼程序员),对于这个需求其实也挺好实现的,就是每次对旋转角度进处理,判断旋转角是是否在规定的范围内,如果在不做处理,如果不在就做一些相应的调整,这个处理要在活动结束处理,也就是在MotionEvent.ACTION_UP这个下边做处理
项目源码Dome地址:https://github.com/suhuMM/DianDianDome.git

猜你喜欢

转载自blog.csdn.net/xiaoxiaohu_/article/details/70257208