Android布局动画
布局动画是指作用在ViewGroup上,给ViewGroup增加View时添加一个动画过渡效果。
最简单的布局动画是在ViewGroup的XML中,使用以下代码来打开布局动画。
android:animateLayoutChanges="true"
通过以上代码设置,当ViewGroup添加View时,子View会呈现逐渐显示的过渡效果,不过这个效果是Android默认的显示的过渡效果,且无法使用自定义的动画来替换这个效果。
另外,还可以通过使用LayoutAnimationController类来自定义一个子View的过渡效果,代码如下所示:
RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl_content);
//设置过渡动画
ScaleAnimation sa = new ScaleAnimation(0, 1, 0, 1);
sa.setDuration(2000);
//设置布局动画的显示属性
LayoutAnimationController lac = new LayoutAnimationController(sa, 0.5f);
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
//为ViewGroup设置布局动画
rl.setLayoutAnimation(lac);
LayoutAnimationController的第一个参数,是需要作用的动画,而第二个参数,则是每个子View显示的delay时间。当delay时间不为0时,可以设置子View显示的顺序,如下所示:
- LayoutAnimationController.ORDER_NORMAL——顺序
- LayoutAnimationController.ORDER_RANDOM——随机
- LayoutAnimationController.ORDER_REVERSE——反序
Interpolators(插值器)
插值器是动画中一个非常重要的概念,通过插值器,可以定义动画变换速率,这一点非常类似物理中的加速度,其作用主要是控制目标变量的变化值进行对应的变化。同样一个动画变换起始值,在不同的插值器作用下,每个单位时间内所达到的变化值也是不一样的。例如一个位移动画,如果使用线性插值器,那么在持续时间内,单位时间所移动的距离都是一样的;如果使用加速度插值器,那么单位时间内所移动的距离先是越来越大后来是越来越小。总之它们的变换速率不一样,但最后都是在相同的规定时间内完成。
自定义动画
创建自定义动画非常简单,只需要实现它的applyTransformation方法的逻辑就可以了,不过通常情况下,还需要覆盖父类的initialize方法来实现一些初始化工作。applyTransformation方法有如下两个参数。
protected void applyTransformation(float interpolatedTime, Transformation t)
第一个参数interpolatedTime就是插值器的时间因子,这个因子是由动画当前完成的百分比和当前时间所对应的插值所计算出来的,取值范围为0到1.0。
第二个参数Transformation非常简单,它是矩阵的封装类,一般使用这个类来获得当前的矩阵对象,代码如下:
Matrix matrix = t.getMatrix();
通过改变获得的matrix对象,可以将动画效果实现出来,而对于matrix的变换操作,基本可以实现任何效果的动画。
模拟电视关闭的效果
电视关闭的效果非常简单,就是让一个图片纵向比例不断缩小即可,对应的矩阵处理方法如下:
/**
* Created by Administrator on 2016/6/2.
* 电视关闭效果的动画
*/
public class TVAnimation extends Animation {
//缩放的中心点,设置为图片的中心即可
private int mCenterWidth;
private int mCenterHeight;
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
// 设置默认时长
setDuration(1000);
// 动画结束后保留状态
setFillAfter(true);
// 设置默认插值器
setInterpolator(new AccelerateInterpolator());
mCenterWidth = width / 2;
mCenterHeight = height / 2;
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
Matrix matrix = t.getMatrix();
matrix.postScale(1, 1 - interpolatedTime, mCenterWidth, mCenterHeight);
}
}
当然,可以设置更精确的插值器,并将0到1.0的时间因子拆分为不同的过程,从而对不同的过程采用不同的动画效果,模拟更加真实的特效。
实现自定义的3D动画效果
结合矩阵,并使用Camera类来实现一个自定义的3D动画效果。要注意的是,这里的Camera并不是指手机中的相机,而是android.graphics.Camera中的Camera类,它封装了openGL的3D动画,从而可以方便地创建3D动画效果。把Camera想象成一个真实的摄像机,当物体固定在某处时,只要移动摄像机就能拍摄到具有立体感的图像,因此通过它可以实现各种3D效果。
自定义动画的核心代码如下:
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
Matrix matrix = t.getMatrix();
mCamera.save();
// 使用Camera设置旋转的角度
mCamera.rotateY(interpolatedTime * mRotateY);
// 将旋转变换作用到matrix上
mCamera.getMatrix(matrix);
mCamera.restore();
// 通过pre方法设置矩阵作用前的偏移量来改变旋转中心
matrix.preTranslate(mCenterWidth, mCenterHeight);
matrix.postTranslate(-mCenterWidth, -mCenterHeight);
}
使用Camera类实现动画效果非常简单,无非就是设置三个坐标轴的旋转角度,不过通过最后两行代码可以改变旋转时默认旋转中心。
效果如如下: