提起动画,会有三种动画类型在Android开发中经常被用到:
这篇文章主要介绍补间动画的原理以及使用
通过确定开始的视图样式和结束的视图样式加入中间动画变化过程来确定一个动画
主要作用于视图控件(如Button,TextView,ImageView等,与帧动画一样)
主要应用于页面的切换。
补间动画主要分为:
以上4种方法均有两种使用方法:一种是以xml方式,一种是以Java形式。下面分别来介绍这4种动画的使用
首先在res下建立一个anim文件夹,在anim文件夹下建立translate.xml文件,文件路径res/anim/translate.xml
translate.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="3000"
android:fillAfter="false"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="infinite"
android:interpolator = "@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000"
android:fromXDelta="0"
android:toXDelta="500"
android:fromYDelta="0"
android:toYDelta="500" />
set>
其次在Java代码中加入启动动画代码:
public class TranslateAnimationActivity extends AppCompatActivity {
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_translate_animation);
// 步骤1:创建 需要设置动画的 视图View
mImageView = findViewById(R.id.iv_image);
// 步骤2:创建 动画对象 并传入设置的动画效果xml文件
Animation translateAnimation = AnimationUtils.loadAnimation(this, R.anim.translate);
// 步骤3:播放动画
mImageView.startAnimation(translateAnimation);
}
}
结果展示:
public class TranslateAnimationActivity extends AppCompatActivity {
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_translate_animation);
// 步骤1:创建 需要设置动画的 视图View
mImageView = findViewById(R.id.iv_image);
/*
创建平移动画的对象:平移动画对应的Animation子类为TranslateAnimation
TranslateAnimation 有三个构造方法
public TranslateAnimation(Context context, AttributeSet attrs) {}
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {}
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue) {}
参数分别是:
1. fromXDelta :视图在水平方向x 移动的起始值
2. toXDelta :视图在水平方向x 移动的结束值
3. fromYDelta :视图在竖直方向y 移动的起始值
4. toYDelta:视图在竖直方向y 移动的结束值
5. pivotXType:平移轴点的x坐标的模式
6. pivotXValue:平移轴点x坐标的相对值
7. pivotYType:平移轴点的y坐标的模式
8. pivotYValue:平移轴点y坐标的相对值
*/
Animation translateAnimation = new TranslateAnimation(0, 500, 0, 500);
// 固定属性的设置都是在其属性前加“set”,如setDuration()
translateAnimation.setDuration(3000);
translateAnimation.setRepeatCount(Animation.INFINITE);
// 步骤3:播放动画
mImageView.startAnimation(translateAnimation);
}
}
效果图同上
首先在res下建立一个anim文件夹,在anim文件夹下建立scale.xml文件,文件路径res/anim/scale.xml
scale.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:duration="3000"
android:fillAfter="false"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="infinite"
android:interpolator = "@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000"
android:fromXScale="0"
android:fromYScale="0"
android:toXScale="5"
android:toYScale="5"
android:pivotX="50%"
android:pivotY="50%"/>
set>
其次在Java代码中加入启动动画代码:
public class ScaleAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scale_animation);
mIvImage = findViewById(R.id.iv_image);
//传入xml文件
Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale);
//开始动画
mIvImage.startAnimation(animation);
}
}
结果展示:
public class ScaleAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scale_animation);
mIvImage = findViewById(R.id.iv_image);
/*
创建缩放动画的对象 & 设置动画效果:缩放动画对应的Animation子类为ScaleAnimation
ScaleAnimation 有四种构造方法
public ScaleAnimation(Context context, AttributeSet attrs) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY) {}
public ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {}
参数说明:
1. fromX :动画在水平方向X的结束缩放倍数
2. toX :动画在水平方向X的结束缩放倍数
3. fromY :动画开始前在竖直方向Y的起始缩放倍数
4. toY:动画在竖直方向Y的结束缩放倍数
5. pivotXType:缩放轴点的x坐标的模式
6. pivotXValue:缩放轴点x坐标的相对值
7. pivotYType:缩放轴点的y坐标的模式
8. pivotYValue:缩放轴点y坐标的相对值
pivotXType = Animation.ABSOLUTE:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
pivotXType = Animation.RELATIVE_TO_SELF:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
pivotXType = Animation.RELATIVE_TO_PARENT:缩放轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)
*/
Animation animation = new ScaleAnimation(0, 5, 0, 5, 0.5f, 0.5f);
animation.setDuration(3000);
animation.setRepeatCount(Animation.INFINITE);
mIvImage.startAnimation(animation);
}
}
效果图同上
首先在res下建立一个anim文件夹,在anim文件夹下建立rotate.xml文件,文件路径res/anim/rotate.xml
rotate.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="3000"
android:fillAfter="false"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="infinite"
android:interpolator = "@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
/>
set>
其次在Java代码中加入启动动画代码:
public class RotateAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rotate_animation);
mIvImage = findViewById(R.id.iv_image);
//传入xml
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate);
//开始动画
mIvImage.startAnimation(animation);
}
}
结果展示:
public class RotateAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rotate_animation);
mIvImage = findViewById(R.id.iv_image);
/*
创建旋转动画的对象 & 设置动画效果:旋转动画对应的Animation子类为RotateAnimation
RotateAnimation 有四种构造方法
public RotateAnimation(Context context, AttributeSet attrs) {}
public RotateAnimation(float fromDegrees, float toDegrees) {}
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {}
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {}
参数说明:
1. fromDegrees :动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
2. toDegrees :动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
3. pivotXType:旋转轴点的x坐标的模式
4. pivotXValue:旋转轴点x坐标的相对值
5. pivotYType:旋转轴点的y坐标的模式
6. pivotYValue:旋转轴点y坐标的相对值
pivotXType = Animation.ABSOLUTE:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 pivotXValue数值的点(y方向同理)
pivotXType = Animation.RELATIVE_TO_SELF:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 自身宽度乘上pivotXValue数值的值(y方向同理)
pivotXType = Animation.RELATIVE_TO_PARENT:旋转轴点的x坐标 = View左上角的原点 在x方向 加上 父控件宽度乘上pivotXValue数值的值 (y方向同理)
*/
Animation animation = new RotateAnimation(0, 360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f);
animation.setRepeatCount(Animation.INFINITE);
animation.setDuration(3000);
mIvImage.startAnimation(animation);
}
}
效果图同上
首先在res下建立一个anim文件夹,在anim文件夹下建立alpha.xml文件,文件路径res/anim/alpha.xml
alpha.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="1000"
android:fillAfter="false"
android:fillBefore="true"
android:fillEnabled="true"
android:repeatCount="infinite"
android:interpolator = "@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000"
android:fromAlpha="1"
android:toAlpha="0"/>
set>
其次在Java代码中加入启动动画代码:
public class AlphaAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alpha_animation);
mIvImage = findViewById(R.id.iv_image);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha);
mIvImage.startAnimation(animation);
}
}
结果展示:
public class AlphaAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alpha_animation);
mIvImage = findViewById(R.id.iv_image);
/*
创建透明度动画的对象 & 设置动画效果:透明度动画对应的Animation子类为AlphaAnimation
AlphaAnimation 有两个构造方法
public AlphaAnimation(Context context, AttributeSet attrs) {}
public AlphaAnimation(float fromAlpha, float toAlpha) {}
参数说明:
1. fromAlpha:动画开始时视图的透明度(取值范围: -1 ~ 1)
2. toAlpha:动画结束时视图的透明度(取值范围: -1 ~ 1)
*/
1.
Animation animation = new AlphaAnimation(1, 0);
animation.setDuration(1000);
animation.setRepeatCount(Animation.INFINITE);
mIvImage.startAnimation(animation);
}
}
效果图同上
写到这里,四种动画的使用就介绍完了,其中Java代码中需要使用的动画子类我已经在代码中添加了注释,下面介绍一下在xml文件中四种动画拥有一部分共有的属性和另一部分自带的属性
共有属性:
android:duration="3000" // 动画持续时间(ms),必须设置,动画才有效果
android:fillAfter="false"// 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
android:fillBefore="true"// 动画播放完后,视图是否会停留在动画开始的状态,默认为true
android:fillEnabled="true"// 是否应用fillBefore值,对fillAfter值无影响,默认为true
android:repeatCount="infinite"// 重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
android:interpolator = "@android:anim/linear_interpolator"// 插值器,即影响动画的播放速度
android:repeatMode="restart"// 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart|
android:startOffset="1000"// 动画延迟开始时间(ms)
平移动画特有属性:
android:fromXDelta="0"// 视图在水平方向x 移动的起始值
android:toXDelta="500"// 视图在水平方向x 移动的结束值
android:fromYDelta="0"// 视图在竖直方向y 移动的起始值
android:toYDelta="500"// 视图在竖直方向y 移动的结束值
缩放动画特有属性:
//这里0表示收缩到没有;1表示正常无伸缩,值小于1表示收缩;值大于1表示放大
android:fromXScale="0"// 动画在水平方向X的起始缩放倍数,
android:fromYScale="0"// 动画在竖直方向y的起始缩放倍数,
android:toXScale="5"//动画在水平方向X的结束缩放倍数
android:toYScale="5"//动画在竖直方向y的结束缩放倍数
android:pivotX="50%"// 缩放轴点的x坐标
android:pivotY="50%"// 缩放轴点的y坐标
/*设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE。
设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向自身高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF
设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向父控件高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT
*/
旋转动画特有属性:
android:fromDegrees="0"// 动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
android:toDegrees="360"// 动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
android:pivotX="50%"// 缩放轴点的x坐标
android:pivotY="50%"// 缩放轴点的y坐标
透明度动画特有属性:
android:fromAlpha="1"// 动画开始时视图的透明度(取值范围: -1 ~ 1)
android:toAlpha="0"// 动画结束时视图的透明度(取值范围: -1 ~ 1)
具体动画可参考文章
首先在res下建立一个anim文件夹,在anim文件夹下建立group.xml文件,文件路径res/anim/group.xml
group.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fillBefore="false"
android:fillEnabled="false"
android:interpolator="@android:anim/linear_interpolator"
android:repeatMode="restart"
android:startOffset="1000">
<rotate
android:duration="3000"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
android:startOffset="100"
android:toDegrees="360" />
<translate
android:duration="1000"
android:fromXDelta="0"
android:fromYDelta="0"
android:startOffset="0"
android:toXDelta="500"
android:toYDelta="500" />
<alpha
android:duration="5000"
android:fromAlpha="1"
android:interpolator="@android:anim/linear_interpolator"
android:startOffset="2000"
android:toAlpha="0" />
set>
其次在Java代码中加入启动动画代码:
public class GroupAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group_animation);
mIvImage = findViewById(R.id.iv_image);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.group);
mIvImage.startAnimation(animation);
}
}
结果展示:
public class GroupAnimationActivity extends AppCompatActivity {
private ImageView mIvImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group_animation);
mIvImage = findViewById(R.id.iv_image);
// 组合动画设置
// 步骤1:创建组合动画对象(设置为true)
AnimationSet setAnimation = new AnimationSet(true);
// 步骤2:设置组合动画的属性
setAnimation.setRepeatMode(Animation.RESTART);
setAnimation.setStartOffset(1000);
setAnimation.setDuration(3000);
// 步骤3:逐个创建子动画(方式同单个动画创建方式,此处不作过多描述)
// 子动画1:旋转动画
Animation rotate = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setDuration(3000);
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
rotate.setStartOffset(100);
// 子动画2:平移动画
Animation translate = new TranslateAnimation(0, 500, 0, 500);
translate.setDuration(1000);
rotate.setStartOffset(0);
// 子动画3:透明度动画
Animation alpha = new AlphaAnimation(1, 0);
alpha.setDuration(5000);
alpha.setStartOffset(2000);
// 步骤4:将创建的子动画添加到组合动画里
setAnimation.addAnimation(rotate);
setAnimation.addAnimation(translate);
setAnimation.addAnimation(alpha);
// 步骤5:播放动画
mIvImage.startAnimation(setAnimation);
}
}
进入其他页面的动画:
startActivity(new Intent(this, ChangeActivity.class));
/*
enterAnim:从Activity a跳转到Activity b,进入b时的动画效果资源ID
exitAnim:从Activity a跳转到Activity b,离开a时的动画效果资源Id
overridePendingTransition()必须要在startActivity(intent)后被调用才能生效
*/
this.overridePendingTransition(R.anim.anim_bottom_in, 0);
退出页面的动画:
@Override
public void onBackPressed() {
super.onBackPressed();
this.overridePendingTransition(0, R.anim.anim_bottom_out);
}
建立xml文件,, 文件路径res/anim/anim_bottom_in.xml
和res/anim/anim_bottom_out.xml
anim_bottom_in.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="600"
android:fromYDelta="100%"
android:toYDelta="0"/>
set>
anim_bottom_out.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="600"
android:fromYDelta="0"
android:toYDelta="100%" />
set>
结果展示:
通过在 Java 代码里setAnimationListener()方法设置
translateAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
//动画开始时执行
}
@Override
public void onAnimationEnd(Animation animation) {
//动画取消时执行
}
@Override
public void onAnimationRepeat(Animation animation) {
//动画重复时执行
}
});
项目源码