##补间动画##
可以使用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);
从第二只小鹿可以看出,它多了一个旋转的效果,但是这个旋转并不是想象中的那样,它旋转的半径很大,也就是旋转的中心点没有选对
这是补间动画的一个弊端,需要属性动画的抱抱才能解决~~
下面就会写属性动画的使用,不要太期待呦~~