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

xiaoxiao2021-02-27  205

补间动画

可以使用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);

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

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

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

转载请注明原文地址: https://www.6miu.com/read-13779.html

最新回复(0)