Android 补间动画了解及使用

本文深入讲解了平移、旋转、缩放和透明度四种补间动画的使用方法,包括XML和Java代码配置,以及如何组合成动画集合,提供了丰富的实例和效果分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

补间动画根据动画效果可以分为四种:平移translate,旋转rotate,缩放scale,透明度alpha。我们可以在xml文件配置(存放路径在res/anim下)或者直接在代码动态配置使用,动画作用于派生自View的控件,不可作用于控件的属性。除了单一的动画效果,我们也可以选择其中几种动画效果组合形成动画集合,接下来让我们具体看下相关使用方法。
因为这几种动画都是继承自Animation,所以在具体使用之前,我们先来了解下Animation的一些属性及其含义:

  • interpolator 设置插值器
  • fillEnabled 设置是否应用fillBefore的值,默认为true
  • fillBefore 设置动画结束时,控件是否恢复开始时状态,默认为true
  • fillAfter 设置动画结束时,控件是否保持结束时状态,默认为false,不受fillEnabled影响,优先级比fillBefore
  • duration 设置一次动画的持续时间,单位是毫秒,必须设置
  • startOffset 设置动画延时启动时间,单位是毫秒
  • repeatCount 设置动画重复次数,设置infinite时为无限循环,默认为0
  • repeatMode 设置动画重复模式,搭配repeatCount使用,restart(正序)/reverse(倒序回放) ,默认为restart
  • zAdjustment 设置动画的内容运行时在Z轴上的位置,normal(保持当前Z轴的位置)/top(置于其他之上)/bottom(置于其他之下),默认为normal

平移动画 TranslateAnimation

TranslateAnimation独有的属性:

  • fromXDelta 起始点X轴坐标,有三种取值方式:具体数值、x%、x%p。设置为具体数值时表示起始点在X轴移动多少数值;设置为x%时表示起始点在X轴移动自己宽度的x%;设置为x%p时,这个p表示取值的基于父控件,即表示起始点在X轴移动父控件宽度的x%。
  • toXDelta 终点X轴坐标 取值方式参考fromXDelta
  • fromYDelta 起始点Y轴坐标 取值方式参考fromXDelta
  • toYDelta 终点Y轴坐标 取值方式参考fromXDelta

XML代码实现,利用translate标签:

//见效果图1中 restart 无限重复 相对于自身宽度
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:duration="2000"
           android:fillAfter="true"
           android:fillBefore="true"
           android:fromXDelta="0"
           android:fromYDelta="0"
           android:toXDelta="20%"
           android:repeatCount="infinite"
           android:toYDelta="300">
</translate>
//见效果图1中 reverse 无限重复 相对于父控件宽度
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:duration="2000"
           android:fillAfter="true"
           android:fillBefore="true"
           android:fillEnabled="true"
           android:fromXDelta="0"
           android:fromYDelta="0"
           android:repeatCount="infinite"
           android:repeatMode="reverse"
           android:toXDelta="20%p"
           android:toYDelta="300"
           android:zAdjustment="normal">
</translate>

使用

        final Animation translateAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.translate_anim);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tv.startAnimation(translateAnimation);
            }
        });

java代码动态设置:
三种取值方式在代码中动态创建对应的就是Animation中的Animation.ABSOLUTE(具体数值),Animation.RELATIVE_TO_SELF(相对于自身),Animation.RELATIVE_TO_PARENT(相对于父控件),看名字定义的就很好理解之前xml所说的了。TranslateAnimation 的构造函数有3个,通常使用后面2个,其中4个参数的取值方式默认为Animation.ABSOLUTE,8个参数的就可以灵活指定取值方式。附上相关源码:

    public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
        mFromXValue = fromXDelta;
        mToXValue = toXDelta;
        mFromYValue = fromYDelta;
        mToYValue = toYDelta;

        mFromXType = ABSOLUTE;
        mToXType = ABSOLUTE;
        mFromYType = ABSOLUTE;
        mToYType = ABSOLUTE;
    }
    public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
            int fromYType, float fromYValue, int toYType, float toYValue) {

        mFromXValue = fromXValue;
        mToXValue = toXValue;
        mFromYValue = fromYValue;
        mToYValue = toYValue;

        mFromXType = fromXType;
        mToXType = toXType;
        mFromYType = fromYType;
        mToYType = toYType;
    }

具体使用

		//对应xml效果1
        TranslateAnimation translateAnim = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_SELF, 0.2f,
                Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 300);
        translateAnim.setRepeatCount(Animation.INFINITE);
        translateAnim.setDuration(2000);
        tv.startAnimation(translateAnim);
		//对应xml效果2
        TranslateAnimation translateAnim2 = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_PARENT, 0.2f,
                Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 300);
        translateAnim2.setRepeatCount(Animation.INFINITE);
        translateAnim2.setRepeatMode(Animation.REVERSE);
        translateAnim2.setDuration(2000);
        tv2.startAnimation(translateAnim2);

效果图1–TranslateAnimation
平移动画

旋转动画 RotateAnimation

RotateAnimation独有的属性:

  • fromDegrees 设置动画开始时旋转的角度 顺时针正值 逆时针为负值
  • toDegrees 设置动画结束时旋转的角度 顺时针正值 逆时针为负值
  • pivotX 旋转轴点X轴坐标点 取值方式参考上面TranslateAnimation 中 fromXDelta属性介绍 默认为0
  • pivotY 旋转轴点Y轴坐标点 同上 默认为0 即旋转轴点默认为控件左上角

XML代码实现,利用rotate标签:

<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fillAfter="true"
        android:fillBefore="true"
        android:fromDegrees="90"
        android:pivotX="50%p"
        android:pivotY="100"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toDegrees="-180">
</rotate>
        Animation rotateAnim = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate_anim);
        tv3.startAnimation(rotateAnim);

java代码实现:

        RotateAnimation rotateAnimation = new RotateAnimation(90, -180, Animation.RELATIVE_TO_PARENT, 0.5f
                , Animation.ABSOLUTE, 100);
        rotateAnimation.setRepeatCount(Animation.INFINITE);
        rotateAnimation.setRepeatMode(Animation.REVERSE);
        rotateAnimation.setDuration(2000);
        tv3.startAnimation(rotateAnimation);

效果图2–RotateAnimation
旋转动画
RotateAnimation 的构造函数就不介绍了,参考TranslateAnimation 使用。现在我们就这个效果来做个分析:
轴点分析
首先轴点的确定:我们设置的属性是X 50%p,Y 100,就是从控件的左上角这个点开始,X轴移动父控件宽度的50%,Y轴移动100;动画的起始旋转角度是90,所以我们顺时针旋转90就是我们的动画起始点,同理动画结束点,是旋转-180,我们逆时针旋转180就确定结束点,我们确定起始结束点都是基于控件的原始位置的。

缩放动画 ScaleAnimation

ScaleAnimation独有的属性:

  • fromXScale 设置动画开始时控件在X轴方向相对于自身的缩放倍数。0就是缩小到没有,1.0无变化,0-1缩小,大于1放大
  • toXScale 设置动画结束控件在X轴方向相对于自身的缩放倍数。具体缩放可参考fromXScale介绍
  • fromYScale 设置动画开始时控件在Y轴方向相对于自身的缩放倍数。参考fromXScale介绍
  • toYScale 设置动画结束控件在Y轴方向相对于自身的缩放倍数。参考fromXScale介绍
  • pivotX 缩放起点X轴坐标。取值方式参考上面TranslateAnimation 中 fromXDelta属性介绍 默认为0
  • pivotY 缩放起点Y轴坐标。取值方式参考上面TranslateAnimation 中 fromXDelta属性介绍 默认为0, 即控件左上角,这与RotateAnimation 的pivotX、pivotY属性含义有所不同,缩放动画的这个点是动画缩放的轴点,RotateAnimation 的是旋转的轴点。

XML代码实现,利用scale标签:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="2000"
       android:fromXScale="1"
       android:fromYScale="0.4"
       android:pivotX="50"
       android:pivotY="30"
       android:repeatCount="infinite"
       android:repeatMode="reverse"
       android:toXScale="1.5"
       android:toYScale="2">
</scale>
        Animation scaleAnim = AnimationUtils.loadAnimation(MainActivity.this, R.anim.scale_anim);
        tv4.startAnimation(scaleAnim);

java代码实现:

		//具体使用参考TranslateAnimation
        ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 1.5f, 0.4f, 2.0f, Animation.ABSOLUTE, 50, Animation.ABSOLUTE, 30);
        scaleAnimation.setRepeatCount(Animation.INFINITE);
        scaleAnimation.setRepeatMode(Animation.REVERSE);
        scaleAnimation.setDuration(2000);
        tv4.startAnimation(scaleAnimation);

效果图3–ScaleAnimation
在这里插入图片描述
当我们把缩小倍数设为负数时,效果会是怎样的呢,我们来实际操作下,我们把X轴方向初始缩放倍数设为-1,Y轴方向初始缩放倍数设为-2:

        ScaleAnimation scaleAnimation = new ScaleAnimation(-1.0f, 1f, -2f, 1f, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0);
        scaleAnimation.setRepeatCount(Animation.INFINITE);
        scaleAnimation.setRepeatMode(Animation.REVERSE);
        scaleAnimation.setDuration(5000);
        tv4.startAnimation(scaleAnimation);

缩放动画2
更多好玩的效果可以自己动手试一试。

透明度动画 AlphaAnimation

AlphaAnimation独有的属性:

  • fromAlpha 设置动画开始时透明度,默认1。 0为全透明 1为不透明
  • toAlpha 设置动画结束时透明度,默认1。 0为全透明 1为不透明

XML代码实现,利用alpha标签:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="5000"
       android:fromAlpha="1"
       android:repeatCount="infinite"
       android:repeatMode="reverse"
       android:toAlpha="0">
</alpha>
        Animation alphaAnim = AnimationUtils.loadAnimation(MainActivity.this, R.anim.alpha_anim);
        tv5.startAnimation(alphaAnim);

java代码实现:

        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.2f);
        alphaAnimation.setRepeatCount(Animation.INFINITE);
        alphaAnimation.setRepeatMode(Animation.REVERSE);
        alphaAnimation.setDuration(5000);
        tv5.startAnimation(alphaAnimation);

效果图4–AlphaAnimation
透明度动画

动画集合 AnimationSet

相对于前面四个动画而言,它们只能完成特定单一的功能,而AnimationSet可以把它们组合起来,完成一个动画。AnimationSet继承自Animation,所以也具有公共属性。

  • shareInterpolator 设置子动画是否和组合共享同一个插值器 AnimationSet的独有属性

XML代码实现,利用set标签:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <translate
        android:duration="2000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toXDelta="50%"
        android:toYDelta="0"/>

    <rotate
        android:duration="1000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:startOffset="2000"
        android:toDegrees="360"/>

    <alpha
        android:duration="3000"
        android:fromAlpha="1.0"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:startOffset="1000"
        android:toAlpha="0.2"/>

    <scale
        android:duration="2000"
        android:fromXScale="1.5"
        android:fromYScale="1.5"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0"
        />

</set>
        Animation setAnim = AnimationUtils.loadAnimation(MainActivity.this, R.anim.set_anim);
        tv6.startAnimation(setAnim);

java代码实现:

        AnimationSet animationSet = new AnimationSet(true);

        TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 0);
        translateAnimation.setRepeatCount(Animation.INFINITE);
        translateAnimation.setRepeatMode(Animation.REVERSE);
        translateAnimation.setDuration(2000);

        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f
                , Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setRepeatCount(Animation.INFINITE);
        rotateAnimation.setRepeatMode(Animation.REVERSE);
        rotateAnimation.setDuration(1000);
        rotateAnimation.setStartOffset(2000);

        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.2f);
        alphaAnimation.setRepeatCount(Animation.INFINITE);
        alphaAnimation.setRepeatMode(Animation.REVERSE);
        alphaAnimation.setDuration(3000);

        ScaleAnimation scaleAnimation = new ScaleAnimation(1.5f, 1.0f, 1.5f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        scaleAnimation.setRepeatCount(Animation.INFINITE);
        scaleAnimation.setRepeatMode(Animation.REVERSE);
        scaleAnimation.setDuration(2000);

        animationSet.addAnimation(translateAnimation);
        animationSet.addAnimation(rotateAnimation);
        animationSet.addAnimation(alphaAnimation);
        animationSet.addAnimation(scaleAnimation);
        tv6.startAnimation(animationSet);

效果图5–AnimationSet
组合动画
注意:

  1. 动画集合中的动画默认是同时开始的,要想实现不同动画不同时间开始,需要给子动画设置延迟开始时间android:startOffset
  2. 当AnimationSet设置公共属性(继承自Animation的属性)会覆盖单个动画设置的属性,但是repeatCount属性除外,这个必须对单个动画设置才有效。

动画监听

最后就是动画执行的状态,我们可以利用AnimationAnimationListener 来监听动画执行的状态

        translateAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                //动画开始触发
                
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                //动画结束触发
                
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                //动画重复执行触发
                
            }
        });

关于补间动画的使用我们暂时就了解到这了,感兴趣的可以自行再去深入了解,当然最重要的还是自己动手操作一番,这样也有助于加深印象,谢谢观看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值