Andorid动画类型
根据动画类型,我们可以将动画分为三大类:
-
帧动画(drawable)
- 可以理解为PPT放映,对预先排好序的drawable resource进行播放。
-
补间动画(animation)
- 只关心动画的开始与结束,其帧与帧之间的效果由动画本身决定,只有View能进行补间动画。
-
属性动画(animator)
- 简单点描述,就是通过不断的更改视图的属性,产生动画效果。
帧动画:
1.在drawable下面放置好自己需要播放的drawable resource
2.在drawable下面新建drawable_animation.xml,并将自己放置好的图片进行排序声明
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true"> <!--动画是否只播放一次-->
<item android:drawable="@drawable/drawable_01" android:duration="500"/>
<item android:drawable="@drawable/drawable_02" android:duration="500"/>
<item android:drawable="@drawable/drawable_03" android:duration="500"/>
</animation-list>
//将声明好的drawable_animation.xml设置为对应view的background
binding.buttonDrawableAnimation.setBackground(AppCompatResources.getDrawable(getActivity(),
R.drawable.draweble_animation));
//使用AnimationDrawable对其进行播放
AnimationDrawable anim = (AnimationDrawable)binding.buttonDrawableAnimation.getBackground();
anim.start();
补间动画:
补间动画有四大类,分别为平移(translate)、缩放(scale)、透明度(alpha)、旋转(rotate)。
补间动画的实现,可以通过res/anim中新建对应的xml及代码中动态声明。
对于补间动画及差值器的实现,建议使用xml方式实现,这样可以提高复用也便于后期维护。
| 动画名称 | xml标签 | 代码子类 | 效果描述 |
|---|---|---|---|
| 平移动画 | translate | TranslateAnimation | 对View进行X轴与Y轴的平移 |
| 缩放动画 | scale | ScaleAnimation | 对View进行基于某个坐标的放大与缩小 |
| 透明度动画 | alpha | AlphaAnimation | 对View进行透明度的改变 |
| 旋转动画 | rotate | RotateAnimation | 对View进行基于某个坐标的旋转 |
- 平移动画(translate)
- xml实现方式:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0%" android:fromYDelta="0%"
android:toXDelta="50%" android:toYDelta="0%"
android:fillAfter= "true"
android:duration = "3000">
</translate>
<!--
fromXDelta 为translateX的起始点,百分比声明为以该控件的width为基准进行百分比计算,若直接声明数值,则为绝对数值。
fromYDelta 为translateY的起始点,百分比声明为以该控件的height为基准进行百分比计算,若直接声明数值,则为绝对数值。
toXDelta 为translateX的终点
toYDelta 为translateY的终点
fillAfter 为动画完成后,是否要以其最终属性填充
-->
- 代码实现方式: TranslateAnimation构造函数:
| 子类名 | 参数 | 参数含义 |
|---|---|---|
| TranslateAnimation | fromXType | Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT,声明X方向上translate是基于绝对数值,基于自身,基于父布局哪种Type. |
| fromXValue | translateX的起始值 | |
| toXType | 同fromXType | |
| toXValue | translateX的终点值 | |
| fromYType | 同fromXType | |
| fromYValue | translateY的起始值 | |
| toYType | 同fromXType | |
| toYValue | translateY的终点值 |
//构造出,基于绝对位置,进行X右移 500, Y下移 500 的translate动画
TranslateAnimation translateAnimation = new TranslateAnimation(
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 500, Animation.ABSOLUTE, 0, Animation.ABSOLUTE, 500);
//设置动画时长
translateAnimation.setDuration(500);
//设置动画结束后,以最终属性填充控件位置
translateAnimation.setFillAfter(true);
//对应view播放该动画
view.startAnimation(translateAnimation);
- 缩放动画(Scale):
- xml实现方式:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale = "100%" android:toXScale = "120%"
android:fromYScale = "100%" android:toYScale = "120%"
android:pivotX = "50%" android:pivotY = "50%"
android:fillAfter = "true" android:duration = "500">
</scale>
<!-- fromXScale 为scaleX的初始值,百分比声明为以该控件的width为基准进行百分比计算
fromYScale 为scaleY的初始值,百分比声明为以该控件的height为基准进行百分比计算
toXScale 为scaleX的终点
toYScale 为scaleY的终点
fillAfter 为动画完成后,是否要以其最终属性填充
上图动画效果则为,基于控件的中心点,控件原width height都扩大至1.2倍。
-->
2.代码实现方式:
ScaleAnimation构造函数:
| 子类名 | 参数 | 参数含义 |
|---|---|---|
| ScaleAnimation | fromX | 在动画开始时,该控件的水平方向起始值 |
| toX | 动画结束时,该控件水平方向的最终值 | |
| fromY | 在动画开始时,该控件的垂直方向起始值 | |
| toY | 动画结束时,该控件的垂直方向的最终值 | |
| pivotXType | Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or Animation.RELATIVE_TO_PARENT,声明pivotXValue 是基于绝对数值、基于自身、基于父布局. | |
| pivotXValue | 要缩放对象的点的X坐标,指定为绝对数,其中0是左边缘。(对象改变大小时,该点保持不变。)如果pivotXType为绝对值,则该值可以是绝对数,否则该值可以是百分比(其中1.0为100%) | |
| pivotYType | 同上pivotXType,声明pivotYValue是基于什么类型 | |
| pivotYValue | 同上pivotXValue,为要缩放对象的点的Y坐标 |
//构造函数,基于view的 width * 0.5f, height * 0.5f 的中心点进行scale 1.5倍动画
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, 1.5f, 1f, 1.5f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(1000);
scaleAnimation.setFillAfter(true);
view.startAnimation(scaleAnimation);
- 透明度动画(Alpha):
1.xml实现方式:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0" android:toAlpha="1"
android:fillAfter = "true" android:duration = "500">
</alpha>
<!--
fromAlpha 透明度起始值
toAlpha 透明度最终值
0为透明 1为不透明
-->
2.代码实现方式:
AlphaAnimation构造函数:
| 子类名 | 参数 | 参数含义 |
|---|---|---|
| AlphaAnimation | fromAlpha | 透明度动画起始值 |
| toAlpha | 透明度动画最终值 |
//构造函数,控件透明度由0f变化为1f
AlphaAnimation alphaAnimation = new AlphaAnimation(0f, 1f);
alphaAnimation.setDuration(2000);
alphaAnimation.setFillAfter(true);
view.setAnimation(alphaAnimation);
- 旋转动画(rotate): 1.xml实现方式:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0" android:toDegrees="90"
android:pivotX="50%" android:pivotY="50%"
android:fillAfter = "true" android:duration = "2000">
</rotate>
<!--
fromDegrees 旋转角度起始值
toDegrees 旋转角度最终值
pivotX 旋转中心点X坐标
pivotY 旋转中心点Y坐标
-->
2.代码实现方式:
RotateAnimation 构造函数:
| 子类名 | 参数 | 参数含义 |
|---|---|---|
| RotateAnimation | fromDegrees | 旋转角度起始值 |
| toDegrees | 旋转角度最终值 | |
| pivotXType | 设置pivotXValue基于绝对数值,自身,父布局类型 | |
| pivotXValue | 对象旋转所围绕的点的X坐标,指定为绝对数,其中0是左边缘。如果pivotXType为绝对值,则该值可以是绝对数,否则该值可以是百分比(其中1.0为100%)。 | |
| pivotYType | 设置pivotYValue基于绝对数值,自身,父布局类型 | |
| pivotYValue | 对象旋转所围绕的点的Y坐标,指定为绝对数,其中0是上边缘。如果pivotYType为绝对值,则该值可以是绝对数,否则该值可以是百分比(其中1.0为100%)。 |
//基于控件中心点,进行0-180度旋转
RotateAnimation rotateAnimation = new RotateAnimation(0f, 180f,
Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
rotateAnimation.setFillAfter(true);
rotateAnimation.setDuration(2000);
view.setAniamtion(rotateAnimation);
-
AnimationListener
对于动画的播放,我们可以通过animation.setAnimationListener进行监听
animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { //动画播放前回调 } @Override public void onAnimationEnd(Animation animation) { //动画结束前回调 } @Override public void onAnimationRepeat(Animation animation) { //动画播放过程中回调 } });我们可以根据对应的回调时机,去做一些业务或交互逻辑。
-
AnimationSet
Set可以理解为集合,AnimationSet则为动画集合,可以将一系列的animation进行组装,然后进行统一播放,这样也可以实现较为复杂的动画交互。
AnimationSet animationSet = new AnimationSet(true); //所有animation使用统一的差值器 animationSet.addAnimation(rotateAnimation); animationSet.addAnimation(translateAnimation); animationSet.setFillAfter(true); animationSet.setDuration(2000); //ms view.startAnimation(animationSet);可以看到,我们可以通过animationSet给所有add进去的animation设置统一的duration, fillAfter等相关的动画属性。同样AnimationSet也可以添加AnimationListener去监听所有动画的播放情况。
-
差值器:
差值器的作用是定义动画的变化率,加速动画,减速动画,重复动画等。
系统为我们提供了一系列默认的差值器类,这里举例几个,就不展开描述了。
子类名 xml id 大致效果 AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 动画始末速度较慢,动画中间过程加速 CycleInterpolator @android:anim/cycle_interpolator 循环播放速率改变为正弦曲线 PathInterpolator null 定义路径坐标,按照路径坐标进行变化 对于平常使用过程,PathInterpolator使用较多,一般该路径参数会由动效同事给出,我们需要按照动效同事给出的path参数,进行差值器构造。
1.xml中构造(res/anim/path_interpolator.xml):
<?xml version="1.0" encoding="utf-8"?> <pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:controlX1="0.17" android:controlY1="0.51" android:controlX2="0.10" android:controlY2="1.00"> </pathInterpolator>我们通过 xml中去将动效同事给出的path参数进行声明,然后在代码中进行读取设置。
PathInterpolator pathInterpolator = (PathInterpolator)AnimationUtils .loadInterpolator(getContext(), R.anim.translate_animation); animationSet.setInterpolator(pathInterpolator);
属性动画:
属性动画(Animator)的几个常用子类
-
ValueAnimator
只关心传入的数据变化区间,而不关心具体是做什么属性变化的动画,需要通过AnimatorUpdateListener的回调,动态接收回调中传回的数值,自己对相关视图的属性进行修改。
ofFloat float类型数据变化
ofArgb argb数据变化
ofInt int类型数据变化
ofObject 自定义数据类型变化
其大致工作流程:
ofInt(0, 100)---->差值器---->数值计算--->updateListene数值返回---->控件属性修改
定义数值变化区间 -> 当前数值 -> 计算后的数值 -> 当前数值通过监听器返回给调用 -> 监听回调设置控件属性变化
-
ObjectAnimator: 构造函数:
public static ObjectAnimator ofFloat(Object target, String propertyName, float… values)
public static ObjectAnimator ofInt(Object target, String propertyName, float… values)
通过我们传入的propertyName(属性名称),其内部会通过该属性名称去寻找target对应的该属性的set/get方法,然后去修改target的对应属性。
//透明度变化 1 -> 0 -> 1
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha",1 , 0, 1);
animator.setDuration(500);
animator.start();
//围绕x轴旋转 0 -> 90 -> 270
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationX", 0,90 ,270);
animator.setDuration(500);
animator.start();
//围绕y轴旋转 0 -> 90 -> 270
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 0,90 ,270);
animator.setDuration(500);
animator.start();
//围绕z轴旋转 0 -> 90 -> 270
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"rotation", 0 ,90 ,270);
animator.setDuration(500);
animator.start();
//在x轴上平移 0 -> 100 -> -100 -> 0
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 0, 100, -100, 0);
animator.setDuration(500);
animator.start();
//在y轴上平移 0 -> 100 -> -100 -> 0
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationY", 0, 100, -100, 0);
animator.setDuration(500);
animator.start();
//在x轴缩放 0.5 -> 1.2 -> 1
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "scaleX", 0.5f, 1.2f, 1f);
animator.setDuration(500);
animator.start();
//在y轴上缩放 0.5 -> 1.2 -> 1
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "scaleY", 0.5f, 1.2f, 1f);
animator.setDuration(500);
animator.start();
-
AnimatorSet:
AnimatorSet与AnimationSet类似,可以将多个Animtor动画进行组合播放
| 函数名 | 效果 | 调用 |
|---|---|---|
| playTogether() | 同时播放多个animtor | playTogether(animator1, animator2 ...) |
| play() | 播放传入的animtor,并返回Budiler | play(animator1) |
| play().with() | 播放传入的animator,并同时播放with传入的 | play(anim1).with(anim2) |
| play().before() | 播放传入的animator,并在前面插入一段animator | play(anim1).before(anim2) |
| play().after() | 播放传入的animator,并在结束后插入一段animator | play(anim2).after(anim2) |
-
差值器:
其含义与上面的animation差值器类似,此处不做过多说明
-
xml实现动画 :
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially" >
<set android:ordering="together" >
<objectAnimator
android:duration="1000"
android:propertyName="translationX"
android:valueFrom="-0"
android:valueTo="100"
android:valueType="floatType" >
</objectAnimator>
<objectAnimator
android:duration="1000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType" >
</objectAnimator>
<set android:ordering="together" >
<objectAnimator
android:duration="1000"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType" >
</objectAnimator>
<objectAnimator
android:duration="1000"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType" >
</objectAnimator>
</set>
</set>
</set>
xml的使用:
Animator animator = AnimatorInflater.loadAnimator(getActivity(), R.anim.translate_animation);
animator.setTarget(buttonView);
animator.start();