Android 属性动画

介绍

属性动画本质就是动态改变View的属性。
PS:属性动画不仅可以改变View的属性。只要是一个对象的属性,有set/get方法,就可以动态的去变化。

先上全部代码:

    private void objectAnimationFromXML() {
        Animator animator = AnimatorInflater.loadAnimator(this, R.animator.translationx);
        animator.setTarget(showView);
        animator.start();
    }

    private void objectAnimationFromJavaCode() {
        //将view的tranlationX属性,在2000ms从0变化到100
        ObjectAnimator.ofFloat(showView, "translationX", 0, 100)
                .setDuration(2000)
                .start();
    }

    private void animatorSet() {
        ObjectAnimator translationX = ObjectAnimator.ofFloat(showView, "translationX", 0, 100)
                .setDuration(2000);
        ObjectAnimator translationY = ObjectAnimator.ofFloat(showView, "translationY", 0, 100)
                .setDuration(2000);
        ObjectAnimator alpha = ObjectAnimator.ofFloat(showView, "alpha", 1.0f, 0.5f)
                .setDuration(2000);
        ObjectAnimator scale = ObjectAnimator.ofFloat(showView, "scaleX", 1.0f, 0.5f)
                .setDuration(2000);
        ObjectAnimator rotate = ObjectAnimator.ofFloat(showView, "rotation", 0, 180)
                .setDuration(2000);

        //以下动画播放顺序,scale->(translationY,alpha)->translationX
        AnimatorSet set = new AnimatorSet();
        set.play(translationY).with(alpha).before(translationX).after(scale);
        //动画5在1000ms后播放。
        set.play(rotate).after(1000);
        set.setDuration(2000);
        set.start();
    }

    private void valueAnimator() {
        ValueAnimator animator = ValueAnimator.ofFloat(0, 100);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                if (value < 50) {
                    showView.setTranslationX(value);
                } else {
                    showView.setTranslationY(value);
                }
            }
        });
        animator.setDuration(2000);
        animator.start();
    }

    private void typeEvaluator() {
        showView.setClipToOutline(true);
        Circle first = new Circle();
        first.setR(0);
        Circle end = new Circle();
        end.setR(showView.getHeight() / 2);

        ValueAnimator animator = ObjectAnimator.ofObject(new CircleEvaluator(), first, end);
        animator.setDuration(2000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                final Circle circle = (Circle) animation.getAnimatedValue();
                showView.setOutlineProvider(new ViewOutlineProvider() {
                    @Override
                    public void getOutline(View view, Outline outline) {
                        outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), circle.getR());
                    }
                });
            }
        });
        animator.start();
    }

    private void interpolator() {
        ObjectAnimator translationX =
                ObjectAnimator.ofFloat(showView, "translationX", 0, 500)
                        .setDuration(2000);
        translationX.setInterpolator(new ReverseInterpolator());
        translationX.start();

    }
    
    private void viewPropertyAnimator() {
        //简单的x轴y轴平移到100的位置,横向纵向放大到2倍,旋转180度,播放时长1s
        showView.animate().x(100).y(100).scaleX(2).scaleY(2).rotation(180).setDuration(1000);
    }

ObjectAnimator

一般情况下,ObjectAnimator类是能属性动画写法简化的一个类。
ObjectAnimator方法有ofInt、ofFloat等方法,传入一个对象,一个对象的属性,一个数值变化范围(如0-100-1000),就会主动调用Object的Set方法不断去设置属性,并触发重绘。
XML动画制作写法:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
                android:duration="2000"
                android:propertyName="translationX"
                android:valueFrom="0"
                android:valueTo="100"
                android:valueType="floatType">
</objectAnimator>

JAVA引用XML文件方法

Animator animator = AnimatorInflater.loadAnimator(context, R.animator.tranlation_animator);
animator.setTarget(view);
animator.start();

JAVA代码动画制作写法:

//将view的tranlationX属性,在2000ms从0变化到100
ObjectAnimator.ofFloat(view,"translationX",0,100)
        .setDuration(2000)
        .start();

AnimatorSet

动画集,关联多个Animator动画。

//以下动画播放顺序,1->(2,3)->4
AnimatorSet set = new AnimatorSet();
set.play(2).with(3).before(4).after(1);
//动画5在1000ms后播放。
set.play(5).after(1000);
set.setDuration(2000);
set.start();

ValueAnimator

ValueAnimator是ObjectAnimator的父类,它相当于只提供了一个数据变化的功能。需要自己去实现数据变化时,具体要执行的操作。大多数时候,我们自定义一些特殊的动画的时候,都是使用ValueAnimator类。
常见用法

ValueAnimator animator = ValueAnimator.ofFloat(0,100);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float value = (float)animation.getAnimatedValue();
    	//数值更新时进行的操作。
    }
});
animator.setDuration(2000);

ps:数值更新时应当使用postInvalidateOnAnimation来优化,postInvalidateOnAnimation 依赖上一帧动画的的执行时间,因为动画的刷新是存在一个频率的,直到下一帧动画的时间才会真正执行刷新操作。

动画监听

AnimatorListener,以上几种类型的动画都支持设置此监听

animator.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
        //动画开始监听
    }

    @Override
    public void onAnimationEnd(Animator animation) {
    	//动画结束监听
    }

    @Override
    public void onAnimationCancel(Animator animation) {
    	//动画取消监听
    }

    @Override
    public void onAnimationRepeat(Animator animation) {
    	//动画重复播放监听
    }
});

同时为了避免重写四个方法的繁琐,提供了AnimatorListenerAdapter类,只需要重写自己想要监听的方法即可。

TypeEvaluator

估值器:简单来说,就是告诉动画系统如何从初始值过渡到结束值。
以常见的ObjectAnimator.ofFloat()方法为例,
FloatEvaluator源码:

public Float evaluate(float fraction, Number startValue, Number endValue) {
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }

可以看出来,其实就是初始值加上变化值。
看起来是不是很简单,但是就这玩意儿我们用好了,就可以实现一系列花里胡哨的动画了,什么圆形变成心形啦,什么心形弹弹弹啦。自定义的话,其实就是实现TypeEvaluator接口的evaluate方法啦~
举个简单的栗子吧:


public class Circle {
    private int r;

    public int getR() {
        return r;
    }

    public void setR(int r) {
        this.r = r;
    }
}

public class CircleEvaluator implements TypeEvaluator<Circle> {

    @Override
    public Circle evaluate(float fraction, Circle startValue, Circle endValue) {
        if (startValue == null || endValue == null) {
            return startValue;
        }
        int startR = startValue.getR();
        int endR = endValue.getR();
        int nowR = startR + (int) (fraction * (endR - startR));
        Circle nowCircle = new Circle();
        nowCircle.setR(nowR);
        return nowCircle;
    }
}

应该很明显就能看出来,这就是个简单的圆半径变化的估值器。大家可以想象一下利用这个玩意儿可以实现什么样的动画啦!

Interpolator

插值器:它的作用概括来说就是控制动画变化的速度。可以看到TypeEvaluator的接口evaluate方法中有一个fraction参数,这个参数的值其实就是根据Interpolator计算得出的。
我们平常使用属性动画时,系统默认的Interpolator其实就是一个先加速后减速的Interpolator,对应的实现类就是AccelerateDecelerateInterpolator。

@HasNativeInterpolator
public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    public AccelerateDecelerateInterpolator() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
    }
}

其中重点是getInterpolation()方法,这个方法就是最终提供给TypeEvaluator使用的fraction。
再举一个简单的栗子:

public class ReverseInterpolator implements Interpolator {
    @Override
    public float getInterpolation(float input) {
        return 1 - input;
    }
}

这就简单的实现倒序的变化啦!是不是很easy!
再推荐大家一个变化函数直观看效果的网站(里面也有很多已经实现好的函数,用起来贼得劲!):
http://inloop.github.io/interpolator/
下面这个网站也包含了很多函数,大家也可以参考一下!
https://easings.net/cn#

ViewPropertyAnimator

专门提供给View的快捷的Animator操作。拥有更好的性能,只执行一次刷新操作就能将所有动画绘制一次,而我们平常使用的Animator每一个都需要绘制一次。

//简单的x轴y轴平移到100的位置,横向纵向放大到2倍,旋转180度,播放时长1s
view.animate().x(100).y(100).scaleX(2).scaleY(2).rotation(180).setDuration(1000);

ViewPropertyAnimator支持的方法还是挺多的,能满足咱们大多数的需求。而且调用真的是很方便!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android属性动画是一种用于在Android应用程序中创建动画效果的框架。它允许您对任意对象的属性进行动画处理,而不仅仅是视图对象。使用属性动画,您可以平滑地改变对象的属性,如位置、大小、颜色等,从而创建流畅的动画效果。 属性动画的基本概念是通过改变对象的属性值来实现动画效果,而不是通过改变视图的位置或绘制来实现。这使得属性动画比传统的补间动画更加灵活和强大。 要使用属性动画,您需要创建一个Animator对象,并指定要动画化的目标对象和属性。然后,您可以定义动画的持续时间、插值器和监听器等属性。最后,启动动画并观察目标对象的属性值的平滑变化。 以下是一个简单的示例,演示如何使用属性动画来平滑地改变视图对象的透明度: ```java // 创建一个属性动画对象,指定要改变的属性为视图对象的透明度 ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha",***.setDuration(1000); // 设置插值器,控制动画的变化速率 animator.setInterpolator(new AccelerateDecelerateInterpolator()); // 启动动画 animator.start(); ``` 在上面的示例中,我们创建了一个ObjectAnimator对象,指定要改变的属性为视图对象的透明度。然后,我们设置了动*** 除了ObjectAnimator,Android还提供了一些其他类型的属性动画,如ValueAnimator和AnimatorSet。这些类可用于更复杂的动画效果,如同时播放多个动画或在动画中修改多个属性。 希望这个简介能帮助您理解Android属性动画的基本概念和用法。如果您有更多问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值