[Android] Su易做图ceView使用实例
同样,先上效果图如下:
效果图中,抛物线的动画即是由Su易做图ceView实现的。底部栏中的文字翻转详情相关帖子:
[Android] 文字翻转动画的实现
需求:
1.实现抛物线动画
1.1 设计物理模型,能够根据时间变量计算出某个时刻图片的X/Y坐标。
1.2 将图片高频率(相比于UI线程的缓慢而言)刷新到界面中。这儿需要实现将脏界面清屏及刷新操作。
2.文字翻转动画(已解决,见上面的帖子链接)
下面来逐一解决所提出的问题。
-----------------------------------------------------------------------------
分隔线内容与Android无关,请慎读,勿拍砖。谢啦
1.1 设计物理模型,如果大家还记得初中物理时,这并不难。自己写的草稿图见下:
可以有:图片要从高度为H的位置下落,并且第一次与X轴碰撞时会出现能量损失,至原来的N%。并且我们需要图片的最终落点离起始位置在X轴上的位移为L,默认存在重力加速度g。
详细的物理分析见上图啦,下面只说代码中如何实现,相关代码在PhysicalTool.java。
第一次下落过程所耗时t1与高度height会有如下关系:
[java]
t1 = Math.sqrt(2 * height * 1.0d / GRAVITY);
第一次与X轴碰撞后上升至最高点的耗时t2与高度 N%*height会有:
[java]
t2 = Math.sqrt((1 - WASTAGE) * 2 * height * 1.0d / GRAVITY);
那么总的动画时间为(t1 + t2 + t2),则水平位移速度有(width为X轴总位移):
[java]
velocity = width * 1.0d / (t1 + 2 * t2);
则根据时间计算图片的实时坐标有:
PhysicalTool.comput()
[java]
double used = (System.currentTimeMillis() - startTime) * 1.0d / 1000;
x = velocity * used;
if (0 <= used && used < t1) {
y = height - 0.5d * GRAVITY * used * used;
} else if (t1 <= used && used < (t1 + t2)) {
double tmp = t1 + t2 - used;
y = (1 - WASTAGE) * height - 0.5d * GRAVITY * tmp * tmp;
} else if ((t1 + t2) <= used && used < (t1 + 2 * t2)) {
double tmp = used - t1 - t2;
y = (1 - WASTAGE) * height - 0.5d * GRAVITY * tmp * tmp;
}
Android无关内容结束了。
----------------------------------------------------------------------------------------
1.2 Su易做图ceView刷新界面
Su易做图ceView是一个特殊的UI组件,特殊在于它能够使用非UI线程刷新界面。至于为何具有此特殊性,将在另一个帖子"Su易做图ceView 相关知识笔记"中讨论,该帖子将讲述Su易做图ceView、Su易做图ce、ViewRoot、Window Manager/Window、Canvas等之间的关系。
使用Su易做图ceView需要自定义组件继承该类,并实现Su易做图ceHolder.Callback,该回调提供了三个方法:
[java]
su易做图ceCreated()//通知Su易做图ce已被创建,可以在此处启动动画线程
su易做图ceChanged()//通知Su易做图ce已改变
su易做图ceDestroyed()//通知Su易做图ce已被销毁,可以在此处终止动画线程
Su易做图ceView使用有一个原则,即该界面操作必须在su易做图ceCreated之后及su易做图ceDestroyed之前。该回调的监听通过Su易做图ceHolder设置。代码如下:
[java]
//于Su易做图ceView类中,该类实现Su易做图ceHolder.Callback接口,如本例中的ParabolaView
Su易做图ceHolder holder = getHolder();
holder.addCallback(this);
示例代码中,通过启动DrawThread调用handleThread()实现对Su易做图ceView的刷新。
刷新界面首先需要执行holder.lockCanvas()锁定Canvas并获得Canvas实例,然后进行界面更新操作,最后结束锁定Canvas,提交界面更改,至Su易做图ce最终显示在屏幕上。
代码如下:
[java]
canvas = holder.lockCanvas();
… … … …
… … … …
canvas.drawBitmap(bitmap, x, y, paint);
holder.unlockCanvasAndPost(canvas);
本例中,需要清除屏幕脏区域,出于简便的做法,是将整个Su易做图ceView背景重复地设置为透明,代码为:
[java]
canvas.drawColor(Color.TRANSPARENT, android.graphics.PorterDuff.Mode.CLEAR);
对于Su易做图ceView的操作,下面这个链接讲述得更详细,更易理解,推荐去看下:
Android开发之Su易做图ceView
惯例,Java代码如下,XML请自行实现
本文由Sodino所有,转载请注明出处:http://blog.csdn.net/sodino/article/details/7704084
[java]
ActSu易做图ceView.java
package lab.sodino.su易做图ceview;
import lab.sodino.su易做图ceview.RotateAnimation.InterpolatedTimeListener;
import android.app.Activity;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
public class ActSu易做图ceView extends Activity implements OnClickListener, ParabolaView.ParabolaListener, Callback,
InterpolatedTimeListener {
public static final int REFRESH_TEXTVIEW = 1;
private Button btnStartAnimation;
/** 动画界面。 */
private ParabolaView parabolaView;
/** 购物车处显示购物数量的TextView。 */
private TextView txtNumber;
/** 购物车中的数量。 */
private int number;
private Handler handler;
/** TextNumber是否允许显示最新的数字。 */
private boolean enableRefresh;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
handler = new Handler(this);
number = 0;
btnStartAnimation = (Button) findViewById(R.id.btnStartAnim);
btnStartAnimation.setOnClickListener(this);
parabolaView = (ParabolaView) findViewById(R.id.su易做图ceView);
parabolaView.setParabolaListener(this);
补充:移动开发 , Android ,