【Android简易动画】计时小球(TimeBall)随时间变化不断跳动的小球
来源:互联网 发布:java图形界面的布局 编辑:程序博客网 时间:2024/05/17 03:39
别的不说,先上效果图
图中的上下两行分别代表的是分钟的数字和秒钟的数字,这个东西是我一个前端的同学首先用JS在网页先实现了效果的,于是我去尝试在Android端实现这个东西,代码我已上传在csdn,欢迎大家一起讨论。 点击这里下载源代码
接下来该讲讲在这次实现功能的过程中遇到的一些问题。由于学到了比较多的东西,一些东西我就精简而过。
首先,要做这个东西,就得先想怎么去实现它,自定义View的实现首当其冲,由于从逻辑上来讲,每个小球都得是一个单独跳动的对象,所以,不得不为每一个小球实例化一个对象,这样一来,在写的时候也会容易有思路,因为就像单独判断一个小球的运动而已。因为要形成动画,所以必须每隔一段时间就重绘一次,这个时候就需要有一个计时操作了。
一开始我用的是在自定义View里面放Handler来实现耗时操作,这显然非常不科学,我就不讲了。。
第二次改,用了List存放每一个运动的小球,在Activity中进行计时操作来实现对控制每个小球运动。
Timer timer = new Timer();TimerTask timerTask = new TimerTask() {@Overridepublic void run() {for(Ball ball:list)ball.falling();}};
一开始每出现什么问题,但是到后来,运动的小球越来越多,资源却没有被回收,导致应用非常消耗资源,所以就想,必须加判断,如果小球不在屏幕内了,将它移出Layout,也移出List。这时候问题就来了,非UI线程中不能进行UI操作,无法从Layout中remove掉没有用的小球,那就想别的办法!于是又用回了Handler。
mHandler = new Handler() {public void handleMessage(android.os.Message msg) {if (msg.what == 1) {for (Ball ball : list) {if (ball.outOfScreen()) {//若小球已不在屏幕内,移出界面,并从list中移出layout.removeView(ball);list.remove(ball);} else //否则继续下掉ball.falling();}sendEmptyMessageDelayed(1, 20);//延迟20毫秒再次发送消息}};};可是这个时候问题又来了!List遍历过程不能中不能删除当前元素,否则会有java.util.ConcurrentModificationException异常,除了Iterator的remove()方法可以实现,一波三折,最终确定为
mHandler = new Handler() {public void handleMessage(android.os.Message msg) {if (msg.what == 1) {Ball ball;for (Iterator iterator = mMovingBall.iterator();iterator.hasNext();) {ball = (Ball) iterator.next();if (ball.outOfScreen()) {//若小球已不在屏幕内,移出界面,并从list中移出mContainer.removeView(ball);iterator.remove();} else//否则继续下掉ball.falling();}sendEmptyMessageDelayed(1, 20);//延迟20毫秒再次发送消息}};};
这里移出小球后,由于java的垃圾回收机制,内存总会被回收的(不保证什么时候回收)。
到这一步解决完了之后,小球的掉落动画明显变得很流畅了。
至于动画的完成,很明显就是调用invalidate()方法,并改变小球的圆心坐标,这时候快速重绘就能形成动画的效果,再判断小球是否触及屏幕底部,如果触及,将竖直方向的速度变为负即可,这样就完成了抛物线式的弹跳(期间可能要考虑“能量消耗”,所以适当减速也可,但是我没有做,因为往往看不出效果的时候,小球就已经跳出屏幕了)。
第一次对View重写,有一个东西也不是很理解,在重新调用invalidate()方法时,为什么上一次onDraw()画的东西不会还留在屏幕上,于是我觉得应该仔细看看invalidate()的实现。
查看了View的源代码,发现invalidate()实际上调用的是draw()方法,而在draw()方法中有以下注释
/* * Draw traversal performs several drawing steps which must be executed * in the appropriate order: * * 1. Draw the background * 2. If necessary, save the canvas' layers to prepare for fading * 3. Draw view's content * 4. Draw children * 5. If necessary, draw the fading edges and restore layers * 6. Draw decorations (scrollbars for instance) */
onDraw过程中绘制的图形是在canvas即画布上的,而画布实质上指的是View的背景,draw()过程的第一步就重新绘制了background,所以原先画的图形并不会保留下来,到第三步中有
// Step 3, draw the content if (!dirtyOpaque) onDraw(canvas);这时候再调用onDraw(),则后来再绘制的图形就覆盖在新的背景上了(若无属性设置背景,则背景为透明)。
0 0
- 【Android简易动画】计时小球(TimeBall)随时间变化不断跳动的小球
- android跳动的小球动画
- Android实现跳动的小球加载动画效果
- java 跳动的小球
- java 跳动的小球
- 跳动的小球
- html5实现跳动的小球的功能
- 非多线程 跳动的小球 Bounce.java
- Firefox os 之跳动的小球
- 小球的自由落体动画
- canvas-小球跳动
- 一个精美的跳动小球—手把手教你用贝塞尔曲线实现一个酷炫跳动动画。
- Android中利用Handler在子线程中更新界面--简单的小球上下跳动案例
- Android中利用Handler在子线程中更新界面--简单的小球上下跳动案例
- Canvas绘制页面小球跳动
- Java Applet 实现一个半径不断增大的彩色小球动画
- Unity基础小案例--跳动的小球、自定义第一人称控制器
- 自己想出来的小球运动的动画(其实不能叫做小球)
- 【软件工程】文档总结
- Ad hoc
- struts2基于注解且使用拦截器的文件上传配置
- 文法也可以通俗易懂
- hdu1027(n个数的按字典序排列的第m个序列)
- 【Android简易动画】计时小球(TimeBall)随时间变化不断跳动的小球
- 二叉查找树与红黑树原理和程序全面介绍
- 别让双手毁了青春!一段关于性成长经历的回忆。。。。。。
- hibernate之6.one2many单向
- YII 访问控制过了filters
- UDP通信编程------利用CAsyncSock类实现UDP异步通信
- Java Thread学习
- childNodes和nodeType
- Android中Adapter之BaseAdapter使用