Android动画案例(二)补间动画

##补间动画##
可以使用xml文件或者java代码进行定义,但是官方推荐xml,但两个同样重要
移动: TranslateAnimation
缩放:ScaleAnimation
旋转:RotateAnimation
透明度:AlphaAnimation
组合动画:AnimationSet 所有的动画文件放置在res/anim目录下,不同的动画有不同的标签
PS:补间动画有一个特性 当动画播放完毕时会恢复到初始状态
###移动###
首先来看一下移动的效果
这里写图片描述
xml文件中定义动画(在res/anim创建xml文件)

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="300"
    android:toYDelta="0"
    android:duration="1000"
    android:interpolator="@android:anim/accelerate_interpolator"
    >
    <!--interpolator 差值器,定义做什么运动-->
</translate>

fromX/YDelta:开始的x/y坐标–px
duration:持续时间—动画的基本属性

为文本框设置动画

这里需要创建一个操作动画的类Animation和对象animation

//为补间动画设置xml文件,并设置到控件上面
    private void translationAnimationXml(){
        //将xml文件加载到动画中
        animation = AnimationUtils.loadAnimation(TweenActivity.this,
                R.anim.translate_tween);
        translation_xml_tv.startAnimation(animation);
    }

这样就可以实现上面的动画了,步骤还是非常的简单

java文件中定义动画

上面是用xml文件设置的动画接下来就用JAVA代码定义动画,正如xml的属性一样,设置两个动画效果一样的动画

 //通过构造方法指定xy坐标
        TranslateAnimation translateAnimation=new TranslateAnimation(0,300,0,0);
        //设置动画差值器(加速差值器)
        translateAnimation.setInterpolator(new AccelerateInterpolator());
        //设置动画的持续时间
        translateAnimation.setDuration(1000);
        translation_java_tv.startAnimation(translateAnimation);

最后在按钮的点击时间中去调用这两个方法就可以启动动画了,但是如果我们想监听动画状态,就可以设置一个动画监听器 ,来监听动画运行到哪一步了

translateAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                Log.d("TAG","onAnimationStart");
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                Log.d("TAG","onAnimationEnd");

            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                //监听动画重复的时候
                Log.d("TAG","onAnimationRepeat");

            }
        });

这里写图片描述
在这里我只是实现了平移,垂直移动,抛物线移动,对角线移动都是可以实现的
###缩放###
同样这里我也使用了两种方法实现:xml和java
首先看一下效果图
这里写图片描述

xml方法的实现
1.定义动画的xml文件
既然是心脏的放大和缩小,这里肯定是要定义两个xml文件分别是放大和缩小
这里写图片描述
to_large:

<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="0.2"
    android:fromYScale="0.2"
    android:toXScale="1.0"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="500"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    >
    <!--从0.2的比例放大到1.0的比例,并以最中间为缩放中心点,做一个500毫秒的减速运动-->
</scale>

fromXScale:动画起始时 X坐标上的伸缩尺寸
fromYScale:动画起始时Y坐标上的伸缩尺寸
toXScale:动画结束时 X坐标上的伸缩尺寸
toYScale: 动画结束时Y坐标上的伸缩尺寸
pivotX:以X坐标的那个点设置缩放
pivotY:以Y坐标的那个点设置缩放

最后两个是 持续时间和差值器,在这里就不过多解释了
还有没有用到的方法
int pivotXType 动画在X轴相对于物件位置类型
float pivotXValue 动画相对于物件的X坐标的开始位置
int pivotYType 动画在Y轴相对于物件位置类型
float pivotYValue 动画相对于物件的Y坐标的开始位置

同理to_small

<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:toXScale="0.2"
    android:toYScale="0.2"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="500"
    android:interpolator="@android:anim/accelerate_interpolator"
   />

在Activity中为控件设置动画
声明动画缩放的类,因为是两个动画(放大和缩小,所以要定义两个类)

 //放大,缩小动画的操作对象
    private Animation toLargeAnimation;
    private Animation toSmallAnimation;
        toLargeAnimation = AnimationUtils.loadAnimation(this, R.anim.to_large);
        toSmallAnimation = AnimationUtils.loadAnimation(this, R.anim.to_small);
        toSmallAnimation.setAnimationListener(this);
        toLargeAnimation.setAnimationListener(this);
        scale_xml_iv.startAnimation(toSmallAnimation);

toSmallAnimation.setAnimationListener(this);
toLargeAnimation.setAnimationListener(this);

就是对动画的监听,上面也提到了,为什么要对动画进行监听呢?
比如我们当前给控件设置的是缩小的动画,但是为了显示出心脏跳动的效果,必须要心脏放大缩小来回的转换,所以当缩小的动画完成后给控件再接着添加上放大的动画,同理放大的动画完成后要回到缩小的动画

 @Override
    public void onAnimationStart(Animation animation) {

    }

    //当动画结束的时候实现对动画进行监听,进行动画的转换
    @Override
    public void onAnimationEnd(Animation animation) {
        Log.d("TAG", "onAnimationEnd");
        //判断当前是哪个动画
        if (animation.hashCode() == toLargeAnimation.hashCode()) {
            scale_xml_iv.startAnimation(toSmallAnimation);
        } else if (animation.hashCode() == toSmallAnimation.hashCode()) {
            scale_xml_iv.startAnimation(toLargeAnimation);
        }
    }

    @Override
    public void onAnimationRepeat(Animation animation) {

    }

这样就完成了缩小放大不断更迭的效果,可以看到我的控制台是不断地在打印log日志的
这里写图片描述
那么如果没有更迭的效果动画又是什么样的呢(只设置scale_xml_iv.startAnimation(toSmallAnimation); 不增加监听事件)
这里写图片描述
图片是先缩小,然后又回到了初始状态

下面是JAVA代码,直接放上

//实例化两个动画操作对象
//private ScaleAnimation toLargeAnimation_java;
//private ScaleAnimation toSmallAnimation_java;
//Animation.RELATIVE_TO_SELF 相对于自己坐标的的50%为中心点进行缩放,要是没有个方法会直接从x轴的0.5f缩放
        toLargeAnimation_java = new ScaleAnimation(0.2f, 1.0f, 0.2f, 1.0f, Animation.RELATIVE_TO_SELF,
                0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        toLargeAnimation_java.setDuration(500);
        toLargeAnimation_java.setInterpolator(new DecelerateInterpolator());
        toSmallAnimation_java = new ScaleAnimation(1.0f, 0.2f, 1.0f, 0.2f, Animation.RELATIVE_TO_SELF,
                0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        toSmallAnimation_java.setDuration(500);
        toSmallAnimation_java.setInterpolator(new AccelerateInterpolator());
        toSmallAnimation_java.setAnimationListener(this);
        toLargeAnimation_java.setAnimationListener(this);
        scale_java_iv.startAnimation(toSmallAnimation_java);

在动画监听事件中的动画更迭

 if (animation.hashCode() == toLargeAnimation_java.hashCode()) {
            scale_java_iv.startAnimation(toSmallAnimation_java);
        } else if (animation.hashCode() == toSmallAnimation_java.hashCode()) {
            scale_java_iv.startAnimation(toLargeAnimation_java);
        }

ScaleAnimation 的构造方法

这里写图片描述

这样动画的移动和缩放就写完了,感觉写了好多东西…
###旋转###
小二~上图!

这里写图片描述
所有的套路都是一样的(我都写的枯燥了)

首先是xml定义动画

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="2000"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:interpolator="@android:anim/linear_interpolator"

    />

fromDegrees:起始旋转度数
toDegrees:旋转多少度
pivotX/Y:以哪个点旋转
repeatCount:重复的次数
repeatMode:重复后旋转的模式

为控件设置动画

        //实例化 Animation rotateAnimationXml
        rotateAnimationXml = AnimationUtils.loadAnimation(this, R.anim.rotate_tween);
        rotate_xml_iv.startAnimation(rotateAnimationXml);

因为在xml文件中定义了动画是无限循环的,所以没有必要在写动画结束的监听,让动画一直旋转下去

用java定义动画

RotateAnimation rotateAnimation = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF,
                0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(2000);
        rotateAnimation.setInterpolator(new LinearInterpolator());
        rotateAnimation.setRepeatCount(Animation.INFINITE);
        rotateAnimation.setRepeatMode(Animation.REVERSE);
        rotate_java_iv.startAnimation(rotateAnimation);
        rotateAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
                Log.d("tag1", "onAnimationStart");

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                Log.d("tag1", "onAnimationEnd");

            }

            @Override
            public void onAnimationRepeat(Animation animation) {
                Log.d("tag1", "onAnimationRepeat");

            }
        });

这里写图片描述

由此可见控制台是没有打印出 onAnimationEnd 的 因为它一直在重复旋转

RotateAnimation 类的构造方法

这里写图片描述

###透明度###

这是两张中毒脸 ,分别是由显示到透明和透明到显示

这里写图片描述

xml 定义的动画是左边效果

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="1.0"
    android:toAlpha="0.1"
    android:duration="2000"
    android:interpolator="@android:anim/accelerate_interpolator"
    >
</alpha>

关键的属性只有两个
fromAlpha:一开始显示的透明度(取值范围从1.0-0.0)
toAlpha:最后的透明度(取值范围从1.0-0.0)

//为控件设置动画
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha_tween);
        alpha_xml_iv.startAnimation(animation);

java代码设置动画

AlphaAnimation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);
        alphaAnimation.setDuration(2000);
        alphaAnimation.setInterpolator(new AccelerateInterpolator());
        alpha_java_iv.startAnimation(alphaAnimation);

透明度动画的设置算是比较简单的了,就不写过多的解释了

###组合动画###
AnimationSet继承自Animation,是上面四中组合容器的 管理类 ,没有自己特有的属性,他的属性继承自Animation

两只非常可爱的小鹿

这里写图片描述

动画效果是水平平移,垂直平移同时进行,这样就形成了斜下方平移的效果,然后两秒后有个透明度的变化

xml文件定义动画

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true"
    android:interpolator="@android:anim/linear_interpolator"
    >
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="200"
        android:toYDelta="0"
        android:duration="2000"
        />
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="200"
        android:duration="2000"/>
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.1"
        android:duration="2000"
        android:startOffset="2000"
        />
</set>

标签里面嵌套着标签呐~

shareInterpolator:是否所有的动画效果都 通用一个差值器
interpolator:差值器是啥
还有一个以前没有用到的属性
startOffset:多长时间之后执行动画

//为控件设置动画
 Animation animation=AnimationUtils.loadAnimation(this,R.anim.set_tween);
        set_xml_iv.startAnimation(animation);

java代码定义动画

//水平平移200
        TranslateAnimation translateAnimationX = new TranslateAnimation(0, 200, 0, 0);
        translateAnimationX.setDuration(2000);
        //垂直平移200
        TranslateAnimation translateAnimationY = new TranslateAnimation(0, 0, 0, 200);
        translateAnimationY.setDuration(2000);
        //透明度变化
        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, .01f);
        alphaAnimation.setDuration(2000);
        alphaAnimation.setStartOffset(2000);
        //旋转变化  补间动画的缺陷:Animation.RELATIVE_TO_SELF旋转的时候会以图片最开始所在的坐标为中心点旋转,
        // 不是以最后到达的地方的中心点
        RotateAnimation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF,
                0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(2000);
        rotateAnimation.setStartOffset(2000);
        AnimationSet animationSet = new AnimationSet(true);
        animationSet.setInterpolator(new LinearInterpolator());
        //添加动画
        animationSet.addAnimation(translateAnimationX);
        animationSet.addAnimation(translateAnimationY);
        animationSet.addAnimation(alphaAnimation);
        animationSet.addAnimation(rotateAnimation);
        set_java_iv.startAnimation(animationSet);

从第二只小鹿可以看出,它多了一个旋转的效果,但是这个旋转并不是想象中的那样,它旋转的半径很大,也就是旋转的中心点没有选对

这是补间动画的一个弊端,需要属性动画的抱抱才能解决~~

下面就会写属性动画的使用,不要太期待呦~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值