和帧动画不同,帧动画 是通过连续播放图片来模拟动画效果,而补间动画开发者只需指定动画开始,以及动画结束"关键帧", 而动画变化的"中间帧"则由系统计算并补齐!
Andoird所支持的补间动画效果有如下这五种,或者说四种吧,第五种是前面几种的组合而已~
AlphaAnimation:透明度渐变效果,创建时许指定开始以及结束透明度,还有动画的持续 时间,透明度的变化范围(0,1),0是完全透明,1是完全不透明;对应 <alpha/> 标签! ScaleAnimation:缩放渐变效果,创建时需指定开始以及结束的缩放比,以及缩放参考点, 还有动画的持续时间;对应 <scale/> 标签! TranslateAnimation:位移渐变效果,创建时指定起始以及结束位置,并指定动画的持续 时间即可;对应 <translate/> 标签! RotateAnimation:旋转渐变效果,创建时指定动画起始以及结束的旋转角度,以及动画 持续时间和旋转的轴心;对应 <rotate/> 标签 AnimationSet:组合渐变,就是前面多种渐变的组合,对应 <set/> 标签。
这里我们先介绍AlphaAnimation、ScaleAnimation、TranslateAnimation、RotateAnimation。
如下是我们用到的类:
android.view.animation.Animation
Animation类是安卓所提供的实现基础动画效果的类,一共有四种不同的效果:半透明渐变、旋转、缩放和移动。可以说所有的复杂动画都可以由这几种基本效果组合而成。而实现这四种效果也非常简单。
android.view.animation.AnimationUtils
AnimationUtils类是Android系统中的动画工具类,提供了控制View对象的一些工具。
android.view.animation.AlphaAnimation
通过改变View的透明度来实现动画效果。
android.view.animation.RotateAnimation
RotateAnimation类是Android系统中的旋转变化动画类,用于控制View对象的旋转动作,该类继承于Animation类。
android.view.animation.ScaleAnimation
Android系统中的尺寸变化动画类,用于控制View对象的尺寸变化,该类继承于Animation类。
android.view.animation.TranslateAnimation
TranslateAnimation类是Android系统中的位置变化动画类,用于控制View对象的位置变化,该类继承于Animation类。TranslateAnimation类中的很多方法都与Animation类一致,该类中最常用的方法便是TranslateAnimation构造方法。
AlphaAnimation、RotateAnimation、ScaleAnimation、TranslateAnimation都继承Animation,因此他们都可以使用Animation的方法。
方法 | 描述 |
---|---|
AlphaAnimation(float fromAlpha, float toAlpha) | AlphaAnimation构造函数 |
RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYTyoe, float pivotYValue) | RotateAnimation构造函数 |
ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYTyoe, float pivotYValue) | ScaleAnimation构造函数 |
TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue) | TranslateAnimation构造函数 |
void addAnimation(Animation a) | 添加定义好的动画效果 |
void setDuration(long durationMillis) | 设置播放时长(毫秒) |
void setRepeatCount(int repeatCount) | 设置重放次数 |
void setRepeatMode(int repeatMode) | 设置重放模式(reverse表示倒序回放,restart表示从头播放) |
void setInterpolator(Interpolator i) | 设置插值器 |
void setFillAfter(boolean fillAfter) | 控件动画结束时是否保持动画最后的状态 |
void setFillBefore(boolean fillBefore) | 控件动画结束时是否还原到开始动画前的状态 |
void setStartOffset(long startOffset) | 调用start函数之后等待开始运行的时间,单位为毫秒 |
void setAnimationListener(AnimationListener listener) | 动画的事件监听 |
这里有一个差值器(interpolator)的概念,我们后续再介绍。
补间动画可以在xml文件中设置,也可以直接在代码中调用各自的类来设置。下面我们两种方法都练习一下。
首先我们在res文件先创建amin目录在分别创建alpha、rotate、scale、tranlslate.xml文件。
alpha.xml(透明度渐变效果)
属性解释:
fromAlpha :起始透明度 toAlpha:结束透明度 透明度的范围为:0-1,完全透明-完全不透明
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="2000" />
</set>
rotate.xml(旋转渐变效果)
属性解释:
fromDegrees/toDegrees:旋转的起始/结束角度
pivotX/pivotY:旋转的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的中心为中轴点进行旋转
repeatCount:旋转的次数,默认值为0,代表一次,假如是其他值,比如3,则旋转4次 另外,值为-1或者infinite时,表示动画永不停止
repeatMode:设置重复模式,默认restart,但只有当repeatCount大于0或者infinite或-1时 才有效。还可以设置成reverse,表示偶数次显示动画时会做方向相反的运动!
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="720"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="1"
android:repeatMode="reverse"
android:duration="2000" />
</set>
scale.xml(缩放渐变效果)
属性解释:
fromXScale/fromYScale:沿着X轴/Y轴缩放的起始比例 toXScale/toYScale:沿着X轴/Y轴缩放的结束比例 pivotX/pivotY:缩放的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的 中心为中轴点进行缩放
epeatCount:缩放的次数,默认值为0,代表一次,
repeatMode:设置重复模式,默认restart
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1"
android:toXScale="10"
android:fromYScale="1"
android:toYScale="10"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="1"
android:repeatMode="reverse"
android:duration="2000" />
</set>
translate.xml(位移渐变效果)
属性解释: fromXDelta/fromYDelta:动画起始位置的X/Y坐标 toXDelta/toYDelta:动画结束位置的X/Y坐标
epeatCount:位移的次数,默认值为0,代表一次,
repeatMode:设置重复模式,默认restart
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="320"
android:toYDelta="320"
android:repeatCount="1"
android:repeatMode="reverse"
android:duration="2000" />
</set>
然后在activity_main.xml键入如下代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="MissingClass">
<ImageView
android:id="@+id/iv"
android:src="@drawable/background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:maxHeight="300dp"
android:maxWidth="300dp"/>
</RelativeLayout>
最后是Activity代码:
package com.example.animationdomo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private int count = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = findViewById(R.id.iv);
//透明度
Animation alphaAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.alpha);
//旋转
Animation rotateAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate);
//缩小
Animation scaleAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.scale);
//平移
Animation translateAnimation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.translate);
//透明度从0到1
AlphaAnimation alphaAnimation1 = new AlphaAnimation(0,1);
alphaAnimation1.setDuration(2000);
//旋转2圈
RotateAnimation rotateAnimation1 = new RotateAnimation(0,720,
Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation1.setDuration(2000);
//放大10倍
ScaleAnimation scaleAnimation1 = new ScaleAnimation(1f,10,1f,10,
Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scaleAnimation1.setRepeatCount(1);
scaleAnimation1.setRepeatMode(Animation.REVERSE);
scaleAnimation1.setDuration(2000);
//平移
TranslateAnimation translateAnimation1 = new TranslateAnimation(
Animation.ABSOLUTE,0, Animation.RELATIVE_TO_PARENT,0.305f,
Animation.ABSOLUTE,0, Animation.RELATIVE_TO_PARENT,0.305f);
translateAnimation1.setRepeatCount(1);
translateAnimation1.setRepeatMode(Animation.REVERSE);
translateAnimation1.setDuration(2000);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(count == 0) {
imageView.startAnimation(alphaAnimation);
count = 1;
}else if(count == 1){
imageView.startAnimation(rotateAnimation);
count = 2;
}else if(count == 2){
imageView.startAnimation(scaleAnimation);
count = 3;
}else if(count == 3){
imageView.startAnimation(translateAnimation);
count = 4;
}else if(count == 4){
imageView.startAnimation(alphaAnimation1);
count = 5;
}else if(count == 5){
imageView.startAnimation(rotateAnimation1);
count = 6;
}else if(count == 6){
imageView.startAnimation(scaleAnimation1);
count = 7;
}else if(count == 7){
imageView.startAnimation(translateAnimation1);
count = 0;
}
}
});
}
}
Domo代码: