【参考链接】
仅通过View.startAnimation()来演示一下如何书写各种TweenAnimation及其效果。
下面可能涉及到绝对值、相对值的概念
| xml | java |
绝对值 | 0、100 | Animation.ABSOLUTE, 0 |
相对值 | -100% | Animation.RELATIVE_TO_SELF, -1f |
50%p | Animation.RELATIVE_TO_PARENT, 0.5f |
alpha
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="reverse"
android:fillAfter="true"
android:fromAlpha="0.0"
android:toAlpha="1.0"
>
</alpha>
public void alpha(View view) {
AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f);
aa.setDuration(2000);
aa.setRepeatCount(1);
aa.setRepeatMode(Animation.REVERSE);
aa.setFillAfter(true);
iv.startAnimation(aa);
// Animation aa = AnimationUtils.loadAnimation(this, R.anim.alpha);
// iv.startAnimation(aa);
}
translate
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:repeatCount="1"
android:repeatMode="reverse"
android:fromXDelta="-100%"
android:toXDelta="0"
android:fromYDelta="0"
android:toYDelta="50%p"
>
</translate>
public void translate(View view) {
TranslateAnimation ta= new TranslateAnimation(
Animation.RELATIVE_TO_SELF, -1f,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_PARENT, 0f,
Animation.RELATIVE_TO_PARENT, 0.5f);
ta.setDuration(3000);
ta.setRepeatCount(1);
ta.setRepeatMode(Animation.REVERSE);
iv.startAnimation(ta);
// Animation ta = AnimationUtils.loadAnimation(this, R.anim.translate);
// iv.startAnimation(ta);
}
rotate
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="4000"
android:repeatCount="1"
android:repeatMode="reverse"
android:fromDegrees="45"
android:toDegrees="360"
android:pivotX="50%p"
android:pivotY="200%"
>
</rotate>
public void rotate(View view) {
RotateAnimation ra = new RotateAnimation(45, 360,
Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_SELF, 2.0f);
ra.setDuration(4000);
ra.setRepeatCount(1);
ra.setRepeatMode(Animation.REVERSE);
iv.startAnimation(ra);
// Animation ra = AnimationUtils.loadAnimation(this, R.anim.rotate);
// iv.startAnimation(ra);
}
scale
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:repeatCount="1"
android:repeatMode="reverse"
android:fromXScale="0.1"
android:toXScale="2.0"
android:fromYScale="0.5"
android:toYScale="1.0"
android:pivotX="0%"
android:pivotY="50%"
>
</scale>
public void scale(View view) {
sa = new ScaleAnimation(0.1f, 2.0f, 0.5f, 1.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f);
sa.setDuration(2000);
sa.setRepeatCount(1);
sa.setRepeatMode(Animation.REVERSE);
iv.startAnimation(sa);
// Animation sa = AnimationUtils.loadAnimation(this, R.anim.scale);
// iv.startAnimation(sa);
}
当缩放点位于View自身区域外时,还会附加位移效果,有点不好描述。
自定义TweenAnimation
在讲自定义TweenAnimation之前,需要先了解一下Interpolator插值器的概念。
插值器的作用是,根据时间流逝的百分比,来计算数据变化的百分比。系统提供了TimeInterpolator接口,其中只定义了一个getInterpolation()方法,用于接收时间流逝的百分比,返回数据变化的百分比。(所以实现起来返回值应该是在0~1之间)
其常用的实现类有
LinearInterpolator,线性插值器
AccelerateInterpolator,加速插值器
DecelerateInterpolator,减速插值器
AccelerateDecelerateInterpolator,加速减速插值器,两头快中间慢
BounceInterpolator,到底以后弹起几次
以LinearInterpolator为例,其getInterpolation()的实现为直接返回时间流逝的百分比,所以是匀速动画。
回到自定义TweenAnimation。要自定义TweenAnimation,需要继承自Animation类并重写它的initialize()和applyTransformation()方法。
对于applyTransformation()方法
第一个参数interpolatedTime即上面Interpolator返回的计算因子,由系统传递到这里来
第二个参数Transformation是Matrix的封装类,可以取出其中的Matrix,并做变换,来实现动画效果。
一个自定义TweenAnimation实例如下(参见《群英传》)
public class CustomTweenAnimation 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);
mCenterWidth = width / 2;
mCenterHeight = height / 2;
// 设置默认时长
setDuration(1000);
// 动画结束后保留状态
setFillAfter(true);
// 设置默认插值器
setInterpolator(new AccelerateInterpolator());
}
@Override
protected void applyTransformation( float interpolatedTime, Transformation t) {
//得到Transformation中的Matrix
final Matrix matrix = t.getMatrix();
matrix.setScale(1, 1 - interpolatedTime,
mCenterWidth,
mCenterHeight);
}
}
直接通过代码使用
CustomTweenAnimationcta = new CustomTweenAnimation();
view.startAnimation(cta);
AnimationSet
可以将多个Animation添加到AnimationSet中,进行多个动画
不过需要注意,多个动画之间并不是独立进行,比如说如下这个示例,位移动画是从左边移动到下边,旋转动画是以自身中心为旋转中心从0°旋转到360°,但叠加起来并不是边位移边绕自身中心旋转。
(如果需要实现这个效果可以考虑自定义)
所以应该也是将多个动画的Matrix计算出一个Matrix再进行变换。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="2000"
android:fromXDelta="-100%"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="50%p"/>
<rotate
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
</set>
// AnimationSet set = new AnimationSet(false); // // TranslateAnimation ta = new TranslateAnimation( // Animation.RELATIVE_TO_PARENT, -0.5f, // Animation.RELATIVE_TO_PARENT, 0.5f, // Animation.RELATIVE_TO_PARENT, -0.5f, // Animation.RELATIVE_TO_PARENT, 0.5f); // ta.setDuration(2000); // ta.setRepeatCount(1); // ta.setRepeatMode(Animation.REVERSE); // // RotateAnimation ra = new RotateAnimation(0, 360, // Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); // ra.setDuration(2000); // ra.setRepeatCount(1); // ra.setRepeatMode(Animation.REVERSE); // // set.addAnimation(ta); // set.addAnimation(ra); // iv.startAnimation(set); Animation set = AnimationUtils.loadAnimation(this, R.anim.set); iv.startAnimation(set); }