谷歌的时候,发现有人罗列了 Animation 的常用方法,转载过来,以作备用。
以下方法不可以被调用使用,只是简单说明下是什么
我们可以将多个动画组合在一起,从而形成一个更加复杂绚丽的动画。
动画组合同样有两种方法:
Java 代码
组合动画需要用到 AnimationSet 对象,该对象接收一个参数:
调用 AnimationSet 对象的 setInterpolator 方法可以为之设置插值器,关于插值器,后面会讲到
创建好 AnimationSet 之后,调用该对象的 addAnimation 就可以将若干个动画添加到集合中,然后再将这个集合设置到组件上,这个组件就可以同时展示若干个动画效果了。
public class MainActivity extends Activity {
private ImageView imageView;
private Button start, stop;
private Animation alphaAnimation, rotateAnimation, scaleAnimation;
private AnimationSet animationSet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.gif);
start = findViewById(R.id.startAnimation);
stop = findViewById(R.id.stopAnimation);
alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
alphaAnimation.setDuration(3000);
alphaAnimation.setRepeatCount(-1);
alphaAnimation.setRepeatMode(Animation.REVERSE);
rotateAnimation = new RotateAnimation(0, 360);
rotateAnimation.setDuration(3000);
rotateAnimation.setRepeatCount(-1);
rotateAnimation.setRepeatMode(Animation.REVERSE);
scaleAnimation = new ScaleAnimation(1.0f, 0.5f, 1.0f, 0.5f);
scaleAnimation.setDuration(3000);
scaleAnimation.setRepeatCount(-1);
scaleAnimation.setRepeatMode(Animation.REVERSE);
animationSet = new AnimationSet(true);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(scaleAnimation);
}
@Override
protected void onStart() {
super.onStart();
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
imageView.startAnimation(animationSet);//启动动画
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// animation.cancel();//取消动画
imageView.clearAnimation();
}
});
}
}
XML 文件定义
在 XML 文件中,我们可以使用 <set>
标签创建集合,在该集合中,假如若干单个动画,组成一个动画集合。
使用上和其他单个动画一样。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="-1"
android:repeatMode="reverse"
android:toDegrees="360" />
</set>
有时候我们需要监听动画进行到哪一步了,就可以为该动画设置一个 AnimationListener,该监听器可以监听到动画开始、结束、重复:
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.d("TTT", "动画开始了");
}
@Override
public void onAnimationEnd(Animation animation) {
Log.d("TTT", "动画结束了");
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.d("TTT", "动画重复执行了");
}
});
Android 提供了一个 Interpolator 接口来帮助我们控制动画的变化速度。
这个东西可以在 XML 当中通过 android:interpolator
属性指定,也可以直接调用 Animation 对象的 setInterpolator 方法指定。
Android 为我们提供了几个个实现类:
LinearInterpolator
动画以均匀的速度改变
AccelerateInterpolator
在动画开始的地方改变速度较慢,然后开始加速
AccelerateDecelerateInterpolator
在动画开始、结束的地方改变速度较慢,中间加速
CycleInterpolator
动画循环播放特定次数,变化速度按正弦曲线改变:Math.sin(2*mCycles*Math.PI*input)
DecelerateInterpolator
在动画划开始的地方改变速度较快,然后开始加速
AnticipateInterpolator
反向,先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator
开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator
跳跃,最快目的的值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100
OvershottInterpolator
回弹,最后超出目的值然后缓慢改变到目的值
Android 提供了 Animation 作为补间动画抽象基类,并且为该抽象基类提供了 AlphaAnimation、RotateAnimation、ScaleAnimation、TranslateAnimation 四个实现类,这四个实现类只是补间动画的四种基本形式:透明度改变、旋转、缩放、位移。在实际项目中可能还需要一些更复杂的动画,比如让图片在“三维”空间内进行旋转动画等。这就需要开发者自己开发补间动画了。
自定义补间动画并不难,需要继承 Animation,继承 Animation 时关键是要重写该抽象基类的 applyTransformation(float interpolatedTime, TransFormation t) 方法,该方法中两个参数说明如下:
interpolatedTime
代表了动画的事件进行比。不管动画实际的持续事件如何,当动画播放时,该参数总是自动从0变化到1;
Transformation
代表了补间动画在不同时刻对图形或组件的变性程度。
从上面的介绍可以看出,实现自定义的关键就在于重写 applyTransformation() 方法时,根据 interpolatedTime 时间来动态的计算动画对图片或视图的变形程度。
Transformation 代表了对图片或视图的变形程度,该对象里封装了一个 Matrix 对象,对它所包装的 Matrix 进行位移、倾斜、旋转等变换,Transformation 将会控制对应的图片或视图进行相应的变换。
为了控制图片或视图进行三维控件的变换,还需要借助于 Android 提供的一个 Camera,这个 Camera 并非代表手机的摄像头,而是一个空间变换工具,作用优点类似于 Matrix,但功能更强大。
Camera提供了如下常用的方法。
getMatrix(Matrix matrix)
将Camera所做的变换应用到指定matrix上
rotateX(float deg)
是目标组件沿X轴旋转
rotateY(float deg)
是目标组件沿Y轴旋转
rotateZ(float deg)
是目标组件沿Z轴旋转
translate(float x, float y, float z)
是目标组件在三维空间里进行位移变换
applyToCanvas(Canvas canvas)
把Camera所做的变换应用到Canvas上
从上面的方法可以看出,Camera 主要用于支持三维空间的变换,那么手机中三维空间的坐标系统是怎样的呢?
当 Camera 控制图片或 View 沿 X、Y 或 Z 轴旋转时,被旋转的图片或 View 将会呈现出三维透视的效果
public class MyAnimation extends Animation
{
private float centerX;
private float centerY;
// 定义动画的持续事件
private int duration;
private Camera camera = new Camera();
public MyAnimation(float x, float y, int duration)
{
this.centerX = x;
this.centerY = y;
this.duration = duration;
}
@Override
public void initialize(int width, int height
, int parentWidth, int parentHeight)
{
super.initialize(width, height, parentWidth, parentHeight);
// 设置动画的持续时间
setDuration(duration);
// 设置动画结束后效果保留
setFillAfter(true);
setInterpolator(new LinearInterpolator());
}
/*
* 该方法的interpolatedTime代表了抽象的动画持续时间,不管动画实际持续时间多长,
* interpolatedTime参数总是从0(动画开始时)~1(动画结束时)
* Transformation参数代表了对目标组件所做的改变.
*/
@Override
protected void applyTransformation(float interpolatedTime
, Transformation t)
{
camera.save();
// 根据interpolatedTime时间来控制X、Y、Z上的偏移
camera.translate(100.0f - 100.0f * interpolatedTime,
150.0f * interpolatedTime - 150,
80.0f - 80.0f * interpolatedTime);
// 设置根据interpolatedTime时间在Y轴上旋转不同角度
camera.rotateY(360 * (interpolatedTime));
// 设置根据interpolatedTime时间在X轴上旋转不同角度
camera.rotateX((360 * interpolatedTime));
// 获取Transformation参数的Matrix对象
Matrix matrix = t.getMatrix();
camera.getMatrix(matrix);
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
camera.restore();
}
}
上面的程序中自定义动画的关键就是
// 设置根据interpolatedTime时间在Y轴上旋转不同角度
camera.rotateY(360 * (interpolatedTime));
// 设置根据interpolatedTime时间在X轴上旋转不同角度
camera.rotateX((360 * interpolatedTime));
这两行代码,这两行代码将会根据动画的进行事件来控制 View 在 X、Y 轴上的旋转——这就会具体在三维空间内旋转的效果。
提供了上面的自定义动画类之后,接下来既可用该自定义动画类来控制图片,也可控制 View 组件,因为动画就是通过调用 View 的 startAnimation(Animation anim) 来启动的。下面是使用 MyAnimation 执行动画的程序代码。
public class MainActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取ListView组件
ListView list = (ListView) findViewById(R.id.list);
WindowManager windowManager = (WindowManager)
getSystemService(WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics metrice = new DisplayMetrics();
// 获取屏幕的宽和高
display.getMetrics(metrice);
// 设置对ListView组件应用动画
list.setAnimation(new MyAnimation(metrice.xdpi / 2
, metrice.ydpi / 2, 3500));
}
}
上面程序中的代码对 ListView 使用 MyAnimation 播放动画,这意味着程序中 ListView 将会以三维变换的动画方式出现,如下图所示
常用方法部分转载自:Android 之 TranslateAnimation类:位移动画类