在进行转场的时候经常需要设置动画,这里提供了animator相关的类

一、关于view的动画

正常用到的有RotateAnimation、TranslateAnimation、ScaleAnimation、AlphaAnimation

也可以多个动画的组合AnimationSet

AnimationSet as = new AnimationSet(true);
        as.setDuration(1000);

        AlphaAnimation aa = new AlphaAnimation(0, 1);
        aa.setDuration(1000);
        as.addAnimation(aa);

        TranslateAnimation ta = new TranslateAnimation(0, 100, 0, 200);
        ta.setDuration(1000);
        as.addAnimation(ta);

        view.startAnimation(as);

如上AnimationSet设置的时间为1000毫秒,然后将AlphaAnimation和TranslateAnimation创建的对象均加到AnimationSet成为组合的方式,最终view的startAnimation(as); 注意最后一定要start,否则不会做效果

使用view操作该AnimationSet的时候view向右下角移动,但是在原来的位置点击依旧会有点击的响应。

 

二、ObjectAnimator

使用ObjectAnimator则不会出现一中的view其他地方移动但是在原来的位置点击依旧响应的情况

通过ObjectAnimator的静态工厂方法可以创建出ObjectAnimator,比如:ObjectAnimator oaa = ObjectAnimator.ofFloat(imageView, "alpha", 0.5f);

工厂方法的第一个参数是要操纵的view,第二个是要操纵的属性,第三个是一个可变的数组参数对应的是属性的变化过程;

如上的ooa的变化过程假设imageView开始的alpha是1,则上面的oaa让imageView从alpha等于1到0.5的一个变化的过程

这里需要注意的是第二个属性必须有对应的get和set方法否则ObjectAnimator无法起效,如果没有对应的get和set方法则需要自己封装一个对应的get和set方法

如下是常见的变换属性

ObjectAnimator移动Android 安卓animator_ide

 

private void AnimatorsOut() {
        ObjectAnimator oaa = ObjectAnimator.ofFloat(mImageViews.get(0), "alpha", 0.5f);
        ObjectAnimator oab = ObjectAnimator.ofFloat(mImageViews.get(1), "translationX", 200);
        ObjectAnimator oac = ObjectAnimator.ofFloat(mImageViews.get(2), "translationX", -200);
        ObjectAnimator oad = ObjectAnimator.ofFloat(mImageViews.get(3), "translationY", 200);
        ObjectAnimator oae = ObjectAnimator.ofFloat(mImageViews.get(4), "translationY", -200);
        AnimatorSet as = new AnimatorSet();
        as.playTogether(oaa, oab, oac, oad, oae); // 这里使用组合的方式,即oaa到oae是一起做动画效果,如果调用as.playSequentially 则是按顺序做效果
        as.setInterpolator(new BounceInterpolator()); // 这里设置了Interpolators(插值器),插值器会让孔吉娜产生不同的动画特效,比如这个BounceInterpolator是反弹,还有其他的特效LinearInterpolator 等
        as.start(); // 设置完成之后,这里调用start才能开始做效果
    }

如上是一个简单的ObjectAnimator的做特效的过程,AnimatorSet用来组装多个特效

 

三、ValueAnimator

使用方式跟ObjectAnimator几乎是一样的,只是它没有ObjectAnimator的第一个参数

ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100);
        // 增加对应的值变更监听
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                ((TextView)view).setText("$ " + (Integer)animation.getAnimatedValue()); // animation.getAnimatedValue() 返回的是object对象,需要强转为对应的类型
            }
        });
        valueAnimator.setDuration(3000); // 设置做动画时间为3秒,动画使用3秒的时间从0到100按顺序调用onAnimationUpdate均匀更新调用,如果调用过程中有卡住的情况,animation.getAnimatedValue()回调的某些值可能会跳过
        valueAnimator.start();

如上所示是ValueAnimator的一个简单调用

 

四、ObjectAnimator和ValueAnimator的监听

安卓提供了一个完整的动画具有Start, Repeat, End, Cancel

animator.addListener(new Animator.AnimatorListener() { 。。。。})

AnimatorListener的接口如下所示:

ObjectAnimator移动Android 安卓animator_ide_02

ObjectAnimator移动Android 安卓animator_ide_03

/**
     * <p>An animation listener receives notifications from an animation.
     * Notifications indicate animation related events, such as the end or the
     * repetition of the animation.</p>
     */
    public static interface AnimatorListener {

        /**
         * <p>Notifies the start of the animation as well as the animation's overall play direction.
         * This method's default behavior is to call {@link #onAnimationStart(Animator)}. This
         * method can be overridden, though not required, to get the additional play direction info
         * when an animation starts. Skipping calling super when overriding this method results in
         * {@link #onAnimationStart(Animator)} not getting called.
         *
         * @param animation The started animation.
         * @param isReverse Whether the animation is playing in reverse.
         */
        default void onAnimationStart(Animator animation, boolean isReverse) {
            onAnimationStart(animation);
        }

        /**
         * <p>Notifies the end of the animation. This callback is not invoked
         * for animations with repeat count set to INFINITE.</p>
         *
         * <p>This method's default behavior is to call {@link #onAnimationEnd(Animator)}. This
         * method can be overridden, though not required, to get the additional play direction info
         * when an animation ends. Skipping calling super when overriding this method results in
         * {@link #onAnimationEnd(Animator)} not getting called.
         *
         * @param animation The animation which reached its end.
         * @param isReverse Whether the animation is playing in reverse.
         */
        default void onAnimationEnd(Animator animation, boolean isReverse) {
            onAnimationEnd(animation);
        }

        /**
         * <p>Notifies the start of the animation.</p>
         *
         * @param animation The started animation.
         */
        void onAnimationStart(Animator animation);

        /**
         * <p>Notifies the end of the animation. This callback is not invoked
         * for animations with repeat count set to INFINITE.</p>
         *
         * @param animation The animation which reached its end.
         */
        void onAnimationEnd(Animator animation);

        /**
         * <p>Notifies the cancellation of the animation. This callback is not invoked
         * for animations with repeat count set to INFINITE.</p>
         *
         * @param animation The animation which was canceled.
         */
        void onAnimationCancel(Animator animation);

        /**
         * <p>Notifies the repetition of the animation.</p>
         *
         * @param animation The animation which was repeated.
         */
        void onAnimationRepeat(Animator animation);
    }

View Code

但是我们正常只会想要其中的一两个借口,那么我们可以使用AnimatorListenerAdapter这个类,如下的调用

animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                view.setVisibility(View.GONE);
            }
        });

这里我只需要end这个借口,则只需要实现该接口即可,无需实现其他的接口

 

5、自定义动画

我们上面介绍的ObjectAnimator和ValueAnimator都是实现Animator接口

我们如果想要实现自定义动画则可以通过实现Animator接口

如下是一个简单的实现过程,调用applyTransformation实现对应的动画逻辑;如果需要初始化,则可以调用initialize 进行一些需要的初始化

public class CustomAnim extends Animation {
    private int mCenterHeight;
    private int mCenterWidth;
    private Camera mCamera = new Camera();
    private float mRotateY = 0;
    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);

        setDuration(2000);
        setFillAfter(true);
        setInterpolator(new AccelerateInterpolator());

        mCenterHeight = height / 2;
        mCenterWidth = width / 2;
    }

    public void setRotateY(float rotateY) {
        mRotateY = rotateY;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        Matrix matrix = t.getMatrix(); // 该矩阵则是当前interpolatedTime动画要显示的效果
        mCamera.save();
        mCamera.rotateY(mRotateY * interpolatedTime);
        mCamera.getMatrix(matrix);
        mCamera.restore();

        matrix.preTranslate(mCenterWidth, mCenterHeight);
        matrix.postTranslate(-mCenterWidth, -mCenterHeight);
    }
}