Android动画基本上可以分为视图动画和属性动画,视图动画包括帧动画和补间动画。
一.概述
通过本篇文章的学习,你将学会:
1.如何使用帧动画
2.如何使用补间动画
3.如何使用属性动画
二.帧动画
帧动画就是按照顺序播放一帧一帧的照片达到动画的效果。我们可以看一下实现过程:
在drawable目录下新建frame_list.xml:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@mipmap/a_0"
android:duration="100" />
<item
android:drawable="@mipmap/a_1"
android:duration="100" />
<item
android:drawable="@mipmap/a_2"
android:duration="100" />
</animation-list>
<!--oneshot表示是否只播放一次,默认false-->
在activity用两个按钮来启动动画和暂停动画:
Button bt_start, bt_stop;
ImageView iv;
AnimationDrawable animationDrawable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_frame);
bt_start = (Button) findViewById(R.id.bt_start);
bt_stop = (Button) findViewById(R.id.bt_stop);
iv = (ImageView) findViewById(R.id.iv);
iv.setImageResource(R.drawable.frame_list);
animationDrawable = (AnimationDrawable) iv.getDrawable();
bt_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//启动帧动画
animationDrawable.start();
}
});
bt_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//暂停帧动画
animationDrawable.stop();
}
});
}
帧动画使用简单方便,但是注意在比较复杂的时候图片比较多的时候容易发生oom,因此尽量避免使用尺寸较大的图片。
三.补间动画
补间动画是通过确定视图开始和结束的样式,然后中间的样式由系统进行补全形成。但是它只是去改变了视觉效果,并不会改变控件本身的属性。补间动画包括基本的平移动画,缩放动画,旋转动画和透明度动画,我们也可以将这些基本动画进行组合在一起。
所有的补间动画共有的属性:
duration:动画时长
startOffset:动画延迟开始时间
fillAfter:动画结束后是否停留在结束状态
repeatMode:重复播放动画模式restart代表正序重放,reverse代表倒序回放
repeatCount:重放次数(+1),为infinite时无限重复
interpolator:插值器:选择动画变化的模式,有匀速,加速,减速,先加速在减速。。。
平移动画
平移动画有其特有的属性,平移动画在水平方向初始值和结束值,在竖直方向的初始值和结束值
有两种方式实现平移动画:
- xml形式:
1.在res目录下新建anim文件夹,创建animation_translate.xml:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:startOffset ="1000"
android:fillAfter = "false"
android:repeatMode= "reverse"
android:repeatCount = "infinite"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXDelta="0"
android:toXDelta="500"
android:fromYDelta="0"
android:toYDelta="0">
<!--duration:动画时长
startOffset:动画延迟开始时间
fillAfter:动画结束后是否停留在结束状态
repeatMode:重复播放动画模式restart代表正序重放,reverse代表倒序回放
repeatCount:重放次数(+1),为infinite时无限重复
interpolator:插值器:选择动画变化的模式,有匀速,加速,减速,先加速在减速。。。
以上是所有补间动画共有的属性,以下是平移动画特有的属性
fromXDelta:平移动画在水平方向x初始值
toXDelta:平移动画在水平方向x结束值
fromYDelta:平移动画在竖直方向y初始值
toYDelta:平移动画在竖直方向y结束值-->
</translate>
各个参数的意义在xml文件中已注明
2.通过AnimationUtils.loadAnimation方法获取Animation对象让控件开始动画:
Animation animation = AnimationUtils.loadAnimation(this, R.anim.animation_translate);
bt_translate.startAnimation(animation);
- java动态执行动画:
//分别对应xml中的fromXDelta,toXDelta,fromYDelta,toYDelta
Animation animation2 = new TranslateAnimation(0, 500, 0, 500);
animation2.setStartOffset(1000);//动画延迟开始时间
animation2.setDuration(3000);//动画持续时长
bt_translate2.startAnimation(animation2);
注意:两种方式都一定需要有duration属性设置动画时长,否则动画不起作用
缩放动画
缩放动画有其特有的属性,缩放动画在水平方向起始缩放倍数和结束缩放倍数,在竖直方向的初始缩放倍数和结束缩放倍数
有两种方式实现缩放动画:
- xml形式:
1.在res的anim目录下创建animation_scale.xml:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:startOffset ="1000"
android:fillAfter = "false"
android:repeatMode= "reverse"
android:repeatCount = "infinite"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXScale="0"
android:toXScale="2"
android:fromYScale="1"
android:toYScale="1"
android:pivotX="50%"
android:pivotY="50%">
<!--fromXScale:动画在水平方向X的起始缩放倍数
fromYScale:动画在竖直方向Y的起始缩放倍数
pivotX:缩放轴点的x坐标
pivotY:缩放轴点的y坐标
pivotX pivotY,可取值为数字,百分比,或者百分比p
设置为数字时(如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-->
</scale>
各个参数的意义在xml文件中已注明
2.通过AnimationUtils.loadAnimation方法获取Animation对象让控件开始动画:
Animation animation = AnimationUtils.loadAnimation(this, R.anim.animation_scale);
bt_scale1.startAnimation(animation);
- java动态执行动画:
//参数分别对应fromXScale,toXScale,fromYScale,toYScale,缩放轴点X坐标类型,pivotX,缩放轴点Y坐标类型,pivotY
Animation animation2 = new ScaleAnimation(0, 2, 0, 2, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation2.setStartOffset(1000);
animation2.setDuration(3000);
bt_scale2.startAnimation(animation2);
注意:两种方式都一定需要有duration属性设置动画时长,否则动画不起作用
旋转动画
旋转动画有其特有的属性,旋转动画在动画开始时视图的旋转角度,在动画结束时视图的旋转角度
有两种方式实现缩放动画:
- xml形式:
1.在res的anim目录下创建animation_rotate.xml:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:startOffset ="1000"
android:fillAfter = "false"
android:repeatMode= "reverse"
android:repeatCount = "infinite"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%">
<!--fromDegrees:动画开始时 视图的旋转角度 正数 = 顺时针,负数 = 逆时针
toDegrees:动画结束时 视图的旋转角度
pivotX:旋转轴点的x坐标
pivotY:旋转轴点的y坐标
pivotX pivotY,可取值为数字,百分比,或者百分比p
设置为数字时(如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-->
</rotate>
各个参数的意义在xml文件中已注明
2.通过AnimationUtils.loadAnimation方法获取Animation对象让控件开始动画:
Animation animation = AnimationUtils.loadAnimation(this, R.anim.animation_rotate);
bt_rotate1.startAnimation(animation);
- java动态执行动画:
//参数分别对应fromDegrees,toDegrees,旋转轴点X坐标类型,pivotX,旋转轴点Y坐标类型,pivotY
Animation animation2 = new RotateAnimation(0, -360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation2.setStartOffset(1000);
animation2.setDuration(3000);
bt_rotate2.startAnimation(animation2);
注意:两种方式都一定需要有duration属性设置动画时长,否则动画不起作用
透明度动画
透明度动画有其特有的属性,透明度动画在动画开始时视图的初始透明度,在动画结束时视图的结束透明度
有两种方式实现透明度动画:
- xml形式:
1.在res的anim目录下创建animation_alpha.xml:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:startOffset ="1000"
android:fillAfter = "false"
android:repeatMode= "reverse"
android:repeatCount = "infinite"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromAlpha="0"
android:toAlpha="1">
<!--fromAlpha:动画开始时视图的初始透明度
toAlpha:动画结束时视图的结束透明度-->
</alpha>
各个参数的意义在xml文件中已注明
2.通过AnimationUtils.loadAnimation方法获取Animation对象让控件开始动画:
Animation animation = AnimationUtils.loadAnimation(this, R.anim.animation_alpha);
bt_alpha1.startAnimation(animation);
- java动态执行动画:
//参数分别对应fromAlpha,toAlpha
Animation animation2 = new AlphaAnimation(0, 1);
animation2.setStartOffset(1000);
animation2.setDuration(3000);
bt_alpha2.startAnimation(animation2);
注意:两种方式都一定需要有duration属性设置动画时长,否则动画不起作用
组合动画
组合动画就是将上面的四种动画组合在一起,同事拥有平移,缩放,旋转和透明度变化的动画。同样有两种方式:
- xml形式:
1.在res目录下新建anim文件夹,创建animation_set.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:duration="1000"
android:fromAlpha="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toAlpha="1" />
<translate
android:duration="2000"
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:startOffset="3000"
android:toXDelta="500"
android:toYDelta="0" />
<rotate
android:duration="3000"
android:fromDegrees="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="restart"
android:toDegrees="360" />
<scale
android:duration="3000"
android:fromXScale="1"
android:fromYScale="1"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="4000"
android:toXScale="0.5"
android:toYScale="0.5" />
</set>
2.通过AnimationUtils.loadAnimation方法获取Animation对象让控件开始动画:
Animation animation = AnimationUtils.loadAnimation(this, R.anim.animation_set);
bt_animation1.startAnimation(animation);
- java动态执行动画:
//动态
bt_animation2 = (Button) findViewById(R.id.bt_animation2);
AnimationSet animationSet = new AnimationSet(true);
//子动画一
Animation animation1 = new AlphaAnimation(0, 1);
animation1.setDuration(1000);
//子动画二
Animation animation2 = new TranslateAnimation(0, 500, 0, 0);
animation2.setDuration(2000);
animation2.setStartOffset(3000);
//子动画三
Animation animation3 = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation3.setDuration(3000);
animation3.setRepeatMode(Animation.RESTART);
animation3.setRepeatCount(Animation.INFINITE);
//子动画四
Animation animation4 = new ScaleAnimation(1, 0.5f, 1, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animation4.setDuration(3000);
animation4.setStartOffset(4000);
animationSet.addAnimation(animation1);
animationSet.addAnimation(animation2);
animationSet.addAnimation(animation3);
animationSet.addAnimation(animation4);
bt_animation2.startAnimation(animationSet);
这样就能实现组合动画。
动画监听
通过setAnimationListener得到动画监听回调,开始和结束
animation2.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
四.属性动画
我们知道帧动画和补间动画都只是改变视觉效果,并没有真正改变控件的属性,因此我们接触到了属性动画,属性动画中一些类的继承关系如下:
我们可以着重看到ValueAnimator,ObjectAnimator和AnimatorSet三个类,因此,属性动画主要围绕这三个类展开,看看属性动画是怎么实现的。
ValueAnimator
通过不断控制值的变化,变化过程中再不断手动赋给对象的属性,从而实现动画效果。
它有三个主要的方法:ValueAnimator.ofInt(int values),ValueAnimator.oFloat(float values)和ValueAnimator.ofObject()。
1.ValueAnimator.ofInt(int values):
它的参数可以传入多个int值,表示多个int值之间进行一个平滑过渡,得到一个动画实例,通过动画的更新监听器将平滑过渡的值传给控件来改变控件的属性打到动画效果。
缩放效果:
bt_value1 = (Button) findViewById(R.id.bt_value1);
//步骤1.创建动画实例,将传入的多个Int参数进行平滑过渡,这里只有两个int参数,可以有多个
ValueAnimator valueAnimator = ValueAnimator.ofInt(bt_value1.getLayoutParams().width, 500);
//步骤2.设置动画的播放各种属性,如动画运行的时长setDuration,动画延迟播放时间setStartDelay,动画重复播放次数setRepeatCount,重复播放动画模式setRepeatMode
valueAnimator.setDuration(3000);
//步骤3.将改变的值手动赋值给对象的属性值:通过动画的更新监听器,值每次改变、变化一次,该方法就会被调用一次
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int currentValue = (int) valueAnimator.getAnimatedValue();
bt_value1.getLayoutParams().width = currentValue;//将当前的值给button作为宽度
bt_value1.requestLayout();//对button进行重新绘制
}
});
//步骤4.开启动画
valueAnimator.start();
平移效果:
bt_value2 = (Button) findViewById(R.id.bt_value2);
ValueAnimator valueAnimator2 = ValueAnimator.ofInt(0, 300);
valueAnimator2.setDuration(3000);
valueAnimator2.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int currentMargin = (int) valueAnimator.getAnimatedValue();
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(bt_value2.getLayoutParams());
layoutParams.setMargins(currentMargin, 0, 0, 0);
bt_value2.setLayoutParams(layoutParams);
}
});
valueAnimator2.start();
透明度效果:
bt_value3 = (Button) findViewById(R.id.bt_value3);
ValueAnimator valueAnimator3 = ValueAnimator.ofFloat(0, 1);
valueAnimator3.setDuration(3000);
valueAnimator3.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float currentValue = (float) valueAnimator.getAnimatedValue();
bt_value3.setAlpha(currentValue);
bt_value3.requestLayout();
}
});
valueAnimator3.start();
接下来主要讲一下ValueAnimator.ofObject()方法的使用。
2.ValueAnimator.ofObject(TypeEvaluator evaluator,Object object):
在补间动画的时候我们有一个interpolator属性是用来设置插值器的用于设置 属性值 从初始值过渡到结束值 的变化规律,诸如减速,加速,匀速,先减速在加速等等这些。该方法的第一个参数是TypeEvaluator表示的是估值器用于设置 属性值 从初始值过渡到结束值 的变化具体数值,也就是根据时间的进度获取该方法第二个参数和第三个参数在变化过程中的数值的方法。前面的ofInt是作用于int数值,ofFloat是作用于Float数值,所以ofObject是作用于对象,我们先创建一个实例对象Point表示控件距离左侧和上侧控件的边距:
public class Point {
// 设置两个变量用于记录控件距离左侧和上侧控件的边距
private int x;
private int y;
// 构造方法用于设置边距
public Point(int x, int y) {
this.x = x;
this.y = y;
}
// get方法用于获取边距
public int getX() {
return x;
}
public int getY() {
return y;
}
}
然后自定义估值器PointEvaluator用于获取根据时间变化过程中的对象objec:
// 实现TypeEvaluator接口
public class PointEvaluator implements TypeEvaluator {
// 复写evaluate()
// 在evaluate()里写入对象动画过渡的逻辑
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
// 将动画初始值startValue 和 动画结束值endValue 强制类型转换成Point对象
Point startPoint = (Point) startValue;
Point endPoint = (Point) endValue;
// 根据fraction来计算当前动画的x和y的值
int x = (int) (startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX()));
int y = (int) (startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY()));
// 将计算后的坐标封装到一个新的Point对象中并返回
Point point = new Point(x, y);
return point;
}
}
我们创建初始对象startPoint和结束对象endPoint,在变化过程中获取当前point对象并给Button设置距离左侧和上侧控件的边距如下:
bt = (Button) findViewById(R.id.bt);
Point startPoint = new Point(0, 0);
Point endPoint = new Point(500, 500);
ValueAnimator valueAnimator = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
valueAnimator.setDuration(3000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Point currentPoint = (Point) valueAnimator.getAnimatedValue();
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(bt.getLayoutParams());
lp.setMargins(currentPoint.getX(), currentPoint.getY(), 0, 0);
bt.setLayoutParams(lp);
bt.requestLayout();
}
});
valueAnimator.start();
这样就实现了Button在3秒时间里从startPoint到endPoint边距的变化过程的动画,这就是ValueAnimator.ofObject的使用
ObjectAnimator
直接对对象的属性值进行改变操作,从而实现动画效果。用法上和ValueAnimator比较类似:
先看下面的对控件进行透明度,平移,缩放和旋转的动画:
bt_alpha = (Button) findViewById(R.id.bt_alpha);
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(bt_alpha, "alpha", 0, 1);
objectAnimator.setDuration(3000);
objectAnimator.start();
bt_translate = (Button) findViewById(R.id.bt_translate);
ObjectAnimator.ofFloat(bt_translate, "translationX", bt_translate.getTranslationX(), 300, bt_translate.getTranslationX()).setDuration(3000).start();
bt_scale = (Button) findViewById(R.id.bt_scale);
ObjectAnimator.ofFloat(bt_scale, "scaleX", 0, 2, 1).setDuration(3000).start();
bt_rotate = (Button) findViewById(R.id.bt_rotate);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(bt_rotate, "rotationY", 0, 360).setDuration(3000);
objectAnimator2.setRepeatCount(ValueAnimator.INFINITE);
objectAnimator2.start();
注意上面ObjectAnimator.ofFloat方法中的第二个参数决定了对控件什么操作,参数名称对应作用见下表:
属性 | 作用 | 数值类型 |
---|---|---|
Alpha | 控制View的透明度 | float |
TranslationX | 控制X方向的位移 | float |
TranslationY | 控制Y方向的位移 | float |
ScaleX | 控制X方向的缩放倍数 | float |
ScaleY | 控制Y方向的缩放倍数 | float |
Rotation | 控制以屏幕方向为轴的旋转度数 | float |
RotationX | 控制以X轴为轴的旋转度数 | float |
RotationY | 控制以Y轴为轴的旋转度数 | float |
注意:ObjectAnimator是对对象的属性值进行改变操作,那么要动画生效,必须满足两个条件:
1.对象必须要提供属性a的set()方法,而且如果没传递初始值,那么需要提供get()方法,因为系统要去拿属性a的初始值
2.属性a的set()方法 对 属性a的改变带来ui上的变化
只有同时满足上面两个条件,动画才会生效。那么如果不满足上面两个条件但是想用怎么办,有两种方法:
1.通过继承原始类,直接给类加上该属性的 get()& set(),从而实现给对象加上该属性的 get()& set()
2.通过包装原始动画对象,间接给对象加上该属性的 get()&set()。即 用一个类来包装原始对象。
比如,width这个属性,虽然控件有set和get的方法,但是控件的set方法并不是设置控件宽度用的,而是设置控件最大宽度和最小宽度的,因此无法去改变控件的宽度,自然动画无法生效。我们可以使用第二种方法进行包装来进行动画改变控件的宽度。先自定义类ViewWrapper添加对View宽度的set个get方法:
public class ViewWrapper {
View view;
public ViewWrapper(View view) {
this.view = view;
}
//得到控件的宽度
public int getWidth() {
return view.getLayoutParams().width;
}
//设置控件的宽度
public void setWidth(int width) {
view.getLayoutParams().width = width;
view.requestLayout();
}
}
在使用ObjectAnimator对ViewWrapper 对象的width属性进行动态改变也就改变了控件的宽度从而达到动画的效果:
bt = (Button) findViewById(R.id.bt);
ViewWrapper viewWrapper = new ViewWrapper(bt);
ObjectAnimator animator = ObjectAnimator.ofInt(viewWrapper, "width", 0, 500);
animator.setDuration(3000);
animator.start();
AnimatorSet
AnimatorSet是组合动画,毕竟淡一点动画还是比较少,很多时候动画都是由单一的属性动画组合在一起。AnimatorSet的使用有如下方法:
AnimatorSet.play(Animator anim) :播放当前动画
AnimatorSet.after(long delay) :将现有动画延迟delay毫秒后执行
AnimatorSet.with(Animator anim) :将现有动画和传入的动画同时执行
AnimatorSet.after(Animator anim) :将现有动画插入到传入的动画之后执行
AnimatorSet.before(Animator anim) : 将现有动画插入到传入的动画之前执行
比如我们需要一个延迟一秒后,先透明度由0-1,然后平移加旋转加缩放的动画:
bt2= (Button) findViewById(R.id.bt2);
//子动画一
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(bt2,"alpha",0,1);
objectAnimator.setDuration(2000);
//子动画二
ObjectAnimator objectAnimator2=ObjectAnimator.ofFloat(bt2,"translationX",0,300);
objectAnimator2.setDuration(3000);
//子动画三
ObjectAnimator objectAnimator3=ObjectAnimator.ofFloat(bt2,"rotation",0,360);
objectAnimator3.setDuration(3000);
//子动画四
ObjectAnimator objectAnimator4=ObjectAnimator.ofFloat(bt2,"scaleX",1,0.5f);
objectAnimator4.setDuration(3000);
//子动画五
ObjectAnimator objectAnimator5=ObjectAnimator.ofFloat(bt2,"scaleY",1,0.5f);
objectAnimator5.setDuration(3000);
AnimatorSet animatorSet=new AnimatorSet();
animatorSet.play(objectAnimator2).with(objectAnimator3).with(objectAnimator4).with(objectAnimator5).after(objectAnimator).after(1000);
animatorSet.start();
ViewPropertyAnimator
属性动画最终都是对控件的值属性进行操作,因此,谷歌也开放了直接用控件进行动画的方法,可以认为是属性动画的简便操作方式:View.animate().xxx();View.animate()返回的是ViewPropertyAnimator,后面调用的方法都是在ViewPropertyAnimator的基础上进行调用开启动画,但是不需要调用start方法去启动。
bt3 = (Button) findViewById(R.id.bt3);
// bt3.animate().alpha(0).setDuration(3000);//透明度由原来变为0
// bt3.animate().translationX(300).setDuration(3000);//平移
// bt3.animate().scaleX(0.5f).scaleY(0.5f).setDuration(3000);//X,Y缩放为原来0.5
bt3.animate().rotation(360).setDuration(3000);//顺时针旋转360度
动画监听
通过addListener添加动画监听得到动画开始,结束,取消方法回调
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
当然,可以使用AnimatorListenerAdapter只监听开始或者结束的其中一个方法:
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
以上就是属性动画相关的用法。
五.总结
以上就是关于Android帧动画,补间动画和属性动画的相关知识点,如有不足或者错误的地方请在下方指正。我们需要多看更需要多写,只有不断学习,不断进步才能不被淘汰。