昨天在郭神的公众号推送里看到了一篇关于小球自由落体动画加载控件的文章推送,就琢磨着班门弄斧做一个小球自由落体动画,适合刚接触自定义View和动画的童鞋学习。
1.知识储备
1.1自定义View
我们知道自定义View主要涉及两个过程,测量和绘制,也就是简单地重写onMeasure()(不过只需要在宽高设定为wrap-content时重写)和onDraw()方法,接下来就自由发挥画出自己想要的效果,详细的方法可以参照我的初探自定义View(一)和初探自定义View(二)。
1.2自定义动画
自定义动画涉及的方法也是主要就两个:
1.2.1applyTransformation(float interpolatedTime, Transformation t)
这个方法是自定义动画的核心方法,定义了动画进行的整个过程。第一个参数interpolatedTime是插值器的时间因子(可以理解成物理中的加速度),决定了这个动画从开始到结束完成过程中的加速度,第二个参数Transformation是矩阵的封装类,一般使用这个类来获得当前的矩阵对象(当前操作的View),然后对该对象进行操作就能实现各种动画效果。
1.2.2initialize(int width, int height, int parentWidth, int parentHeight)
这个方法主要是通过覆写父类的initialize()来进行一些初始化工作。
2.实现过程
2.1小球的绘制
public void init(){
//初始化
mCirclePaint=new Paint();
mCirclePaint.setColor(Color.RED);
mCirclePaint.setStyle(Paint.Style.FILL);
}
//绘制
public void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawCircle(x,y,r,mCirclePaint);
}
@Override
protected void onSizeChanged(int w,int h,int oldW,int oldH){
super.onSizeChanged(w,h,oldW,oldH);
length = w; //这里的w指的是在xml文件中设定的宽度width的值
//确定圆心坐标和半径
x = length/2;
y = length/8;
r = (float) (length*0.5/8);
}
添加到布局文件中:
<com.example.animation.Ball
android:id="@+id/ball"
android:layout_width="400dp"
android:layout_height="400dp" />
经过上述过程小球就画好了,如图:
2.2动画效果的实现
public class OpenGL extends Animation {
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
setDuration(2000);// 设置默认时长
setFillAfter(true);// 动画结束后保留状态
setInterpolator(new BounceInterpolator());// 设置插值器
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final Matrix matrix = t.getMatrix();
matrix.preTranslate(0,700 * interpolatedTime);
}
}
首先覆写父类的initialize()方法进行初始化setInterpolator(new BounceInterpolator());
这个方法是这个实现自由落体效果的关键,BounceInterpolator这个插值器的取值为0-1,而且从0变到1的速度越来越快,可以理解成物理场景中的匀加速运动,而且在结束后还有一个弹跳的效果。
更多插值器效果
matrix.preTranslate(0,1000 * interpolatedTime);
这个可以理解成View的实时坐标(x,y),注意这里的x其实是Δx,表示View在移动前的坐标和移动过程中的差值,0就代表这是一个竖直方向上的运动。
final OpenGL open=new OpenGL();
ball.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ball.startAnimation(open);
}
});
最后调用这个动画类的实例就能实现这一效果: