动画类型
View Animation(视图动画)
- Tween Animation(补间动画)
- Frame Animation(逐帧动画)
Property Animation(属性动画)
- ValueAnimator
- ObjectAnimator
一. 视图动画标签
1.概述
Android动画由5种类型组成:alpha、scale、translate、rotate、set
1.1配置XML动画文件
常用标签:
- alpha:渐变透明度动画
- scale:渐变尺寸伸缩动画
- translate:画面变换位置移动动画
- rotate:画面转移旋转动画
- set:定义动画集
| <?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android"
 android:fromXScale="0.0"
 android:toXScale="1.4"
 android:fromYScale="0.0"
 android:toYScale="1.4"
 android:pivotX="50%"
 android:pivotY="50%"
 android:duration = "1000">
 </scale>
 
 | 
1.2 动画文件存放位置
动画文件应该放于res/anim文件夹下,访问时使用R.anim.XXX
1.3 使用动画文件
| Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.scale_down_anim);textView.startAnimation(animation);
 
 
 | 
动画开始时,会将TextView的高度、宽度都从0缩放到1.4倍大小
1.4 scale标签
scale标签用于缩放动画,该标签有如下几个属性
- android:fromXScale:动画起始时,控件在X轴方向相对自身的缩放比例,浮点值,比如,1.0代表自身无变化,0.5代表缩放1倍,2.0代表放大1倍
- android:toXScale:动画结束时,控件在X轴相对自身的缩放比例,浮点值。
- android:fromYScale:动画起始时,控件在Y轴方向相对自身的缩放比例,浮点值。
- android:toYScale:动画结束时,控件在Y轴方向相对自身的缩放比例,浮点值。
- android:pivotX:缩放起始点X轴坐标,可以是数值、百分数、百分数p 三种样式,如50、50% 、50%p 。如果是数值, 表示在当前视图的左上角 ,即原点处加 50px,作为缩放起始点X轴坐标;如果是 50% 则表示在当前控件的左上角加上自己宽度的50%作为缩放起点X轴坐标;如果是50%p,则表示在当前父控件的左上角加上父控件宽度的50%作为缩放起始点X轴坐标。
- android:pivotY:缩放起始点X轴坐标,取值及含义与 android:pivotX相同。
| <?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android"
 android:fromXScale="0.0"
 android:toXScale="1.4"
 android:fromYScale="0.0"
 android:toYScale="1.4"
 android:pivotX="50%"
 android:pivotY="50%"
 android:fillAfter="true"
 android:duration="2000"/>
 
 | 
1.5 Animation继承属性
所有的动画都继承Animation类
以 scale标签为例,讲述Animation类所具有的属性及其含义
- android:duration:用于设置一次动画的持续时间,以毫秒为单位。
- android:fillAfter:如果设置为 true,则控件动画结束时,将保持动画结束时的状态。
- android:fillBefore:如果设置为 true,则控件动画结束时,将还原到初始化状态。
- android fil!Enabed:与android:fillBefore 效果相同,都是在控件动画结束时,将还原到初始化状态。
- android:repeatCount:用于指定动画的重复次数,当取值为- infinite时, 表示无限循环。
- android:repeatMode:用于设定重复的类型,有 reverse和restart两个值,其中reverse表示倒序回放: restart 表示重放,并且必须与- repeatCount 一起使用才能看到效果。
- android:interpolator:用于设定插值器,其实就是指定的动画效果,比如弹跳效果等。
| <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"
 android:fillAfter="true"
 >
 <scale android:fromXScale="1.0"
 android:toXScale="0.4"
 android:fromYScale="1.0"
 android:toYScale="0.6"
 android:pivotY="50%"
 android:pivotX="50%"
 android:repeatMode="reverse"
 android:repeatCount="2"
 android:duration="700"/>
 </set>
 
 | 
1.6 alpha标签
标签属性:
- android:fromAlpha: 动画开始时的透明度,取值范围为 0~ 1 .0, 0.0表示全透明, 1.0表示完全不透明。
- android:toAlpha: 动画结束时的透明度
| <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"
 android:duration="3000"
 android:fillBefore="true">
 <alpha android:fromAlpha="1.0"
 android:toAlpha="0.1"
 />
 </set>
 
 | 
1.7 rotate标签
rotate标签用于实现画面转移旋转动画效果,标签属性:
- android:fromDegress:动画开始旋转时的角度位置,正值代表顺时针方向的度数,负值代表逆时针方向的度数
- android:toDegress:动画结束时旋转到的角度位 ,正值代表顺时针方向的度数,负值代表逆时针方向的度数
- android:pivotX:旋转中心点X轴坐标,默认旋转中心点是控件坐标原点。        可以是数值、百分数、 百分数p 三 种样式,比如 50 50% 50%p ,具体含义己在 scale 标签中讲述。
- android:pivotY:旋转中心点Y轴坐标。
| <?xml version="1.0" encoding="utf-8"?><rotate xmlns:android="http://schemas.android.com/apk/res/android"
 android:duration="6000"
 android:fromDegrees="0"
 android:pivotX="50%"
 android:pivotY="50%"
 android:toDegrees="1080" />
 
 
 
 
 | 
1.8 translate标签
translate标签用于实现画面变换位置移动动画效果。属性:
- android:fromXDelta:起始点X轴坐标,可以是是数值、百分数、百分数p 三种样式。
- android:fromYDelta:起始点Y轴坐标
- android:toXDelta:终点X轴坐标
- android:toYDelta:终点Y轴坐标
| <set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true">
 
 <translate
 android:duration="2000"
 android:fromXDelta="0"
 android:fromYDelta="0"
 android:toXDelta="-80"
 android:toYDelta="-80" />
 </set>
 
 | 
1.9 set标签
| <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"
 android:duration="3000"
 android:fillAfter="true">
 <alpha
 android:fromAlpha="0.0"
 android:toAlpha="1.0" />
 <scale
 android:fromXScale="0.0"
 android:fromYScale="0.0"
 android:pivotX="50%"
 android:pivotY="50%"
 android:toXScale="1.4"
 android:toYScale="1.4" />
 <rotate
 android:fromDegrees="0"
 android:pivotX="50%"
 android:pivotY="50%"
 android:toDegrees="720" />
 </set>
 
 | 
控件完成了从小到大,旋转出场,透明度从0到1的组合效果。
注意:在 set 标签中设直 repeateCount 属性是无效的,必须对每个动画单独设直才有作用
二、视图动画的代码实现
标签与所对应的类如下所示
| scale | ScaleAnimation | 
| alpha | AlphaAnimation | 
| rotate | RotateAnimation | 
| translate | TranslateAnimation | 
| set | AnimationSet | 
2.1 ScaleAnimation
与1.4节XML对应的代码是:
| Animation scaleAnimation = new ScaleAnimation(0,1.4f,0,1.4f,
 Animation.RELATIVE_TO_SELF,0.5f,
 Animation.RELATIVE_TO_SELF,0.5f);
 scaleAnimation.setDuration(2000);
 scaleAnimation.setFillAfter(true);
 
 | 
2.2 AlphaAnimation
与1.6节对应的代码是:
| Animation alphaAnimation = new AlphaAnimation(0.0f,1.0f);alphaAnimation.setDuration(3000);
 alphaAnimation.setFillBefore(true);
 
 | 
2.3 RotateAnimation
与1.7节对应的代码是:
| Animation rotateAnimation = new RotateAnimation(0,1080,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
 rotateAnimation.setDuration(6000);
 
 | 
2.4 TranslateAnimation
与1.8节对应的代码是:
| Animation translateAnimation = new TranslateAnimation(0,-80,0,-80);translateAnimation.setDuration(2000);
 
 | 
2.5 AnimationSet
与1.9对应的代码是:
| AnimationSet animationSet = new AnimationSet(true);
 
 Animation alphaAnimation = new AlphaAnimation(0.0f,1.0f);
 Animation scaleAnimation = new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,
 Animation.RELATIVE_TO_SELF,0.5f,
 Animation.RELATIVE_TO_SELF,0.5f);
 Animation rotateAnimation = new RotateAnimation(0,720,
 Animation.RELATIVE_TO_SELF,0.5f,
 Animation.RELATIVE_TO_SELF,0.5f);
 
 animationSet.addAnimation(alphaAnimation);
 animationSet.addAnimation(scaleAnimation);
 animationSet.addAnimation(rotateAnimation);
 
 animationSet.setDuration(3000);
 animationSet.setFillAfter(true);
 binding.textView.startAnimation(animationSet);
 
 | 
2.7 Animation
其他函数
| void cancel() void reset()
 void setAnimationListener(Animation.AnimationListener listener)
 
 | 
示例:
| animationSet.setAnimationListener(new Animation.AnimationListener() {@Override
 public void onAnimationStart(Animation animation) {
 }
 
 @Override
 public void onAnimationEnd(Animation animation) {
 animationSet.reset();
 showTranslateAnimation();
 }
 @Override
 public void onAnimationRepeat(Animation animation) {
 
 }
 });
 
 | 
三、 插值器
插值器是在 XML 中定义的动画修改器,它会影响动画的变化率。插值器可对现有的动画效果执行加速、减速、重复、退回等。
插值器通过 android:interpolator 属性应用于动画元素,该属性的值是对插值器资源的引用。
Android 中提供的所有插值器都是 Interpolator 类的子类。为便于您使用 android:interpolator 属性将插值器应用于动画,Android 针对每个插值器类包含了一个可供您引用的公共资源。下表指定了每个插值器要使用的资源:
您可以通过以下方式使用 android:interpolator 属性应用上述某个插值器:
| <set android:interpolator="@android:anim/accelerate_interpolator">...
 </set>
 
 | 
自定义插值器
如果您对平台提供的插值器(在上表中列出)不满意,则可以使用修改过的属性创建自定义插值器资源。例如,您可以调整 AnticipateInterpolator 的加速率或调整 CycleInterpolator 的循环次数。为此,您需要在 XML 文件中创建自己的插值器资源。
文件位置:
res/anim/*filename*.xml
该文件名将用作资源 ID。
编译后的资源数据类型:
指向相应插值器对象的资源指针。
资源引用:
在 XML 中:@[*package*:]anim/*filename*
语法:
| <?xml version="1.0" encoding="utf-8"?><InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"
 android:attribute_name="value"
 />
 
 | 
如果您不应用任何属性,则您的插值器的运作方式将与平台提供的插值器(在上表中列出)完全相同。
元素:
请注意,在 XML 中定义的每个 Interpolator 实现的名称都以小写字母开头。
- <accelerateDecelerateInterpolator>
 - 变化率在开始和结束时缓慢,但在中间会加快。无属性。 
- <accelerateInterpolator>
 - 变化率在开始时较为缓慢,然后会加快。属性:- android:factor浮点数。加速率(默认为 1)。
 
- <anticipateInterpolator>
 - 先反向变化,然后再急速正向变化。属性:- android:tension浮点数。要应用的张力(默认为 2)。
 
- <anticipateOvershootInterpolator>
 - 先反向变化,再急速正向变化并超过目标值,然后以最终值结束。属性:- android:tension浮点数。要应用的张力(默认为 2)。- android:extraTension浮点数。张力要乘以的倍数(默认值为 1.5)。
 
- <bounceInterpolator>
 - 变化会在结束时退回。无属性。 
- <cycleInterpolator>
 - 按指定的循环次数重复动画。变化率符合正弦曲线图。属性:- android:cycles整数。循环次数(默认值为 1)。
 
- <decelerateInterpolator>
 - 变化率开始时很快,然后减慢。属性:- android:factor浮点数。减速率(默认值为 1)。
 
- <linearInterpolator>
 - 变化率恒定不变。无属性。 
- <overshootInterpolator>
 - 先急速正向变化,再超过最终值,然后回到最终值。属性:- android:tension浮点数。要应用的张力(默认为 2)。
 
示例:
保存在 res/anim/my_overshoot_interpolator.xml 的 XML 文件:
| <?xml version="1.0" encoding="utf-8"?><overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
 android:tension="7.0"
 />
 
 | 
此动画 XML 将应用插值器:
| <scale xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@anim/my_overshoot_interpolator"
 android:fromXScale="1.0"
 android:toXScale="3.0"
 android:fromYScale="1.0"
 android:toYScale="3.0"
 android:pivotX="50%"
 android:pivotY="50%"
 android:duration="700" />
 
 | 
四、动画示例
4.1 镜头由远及近效果
| ScaleAnimation scaleAnimation = new ScaleAnimation(1f,1.1f,1f,1.1f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
 scaleAnimation.setDuration(3*1000L);
 scaleAnimation.setFillAfter(true);
 binding.imageView.setAnimation(scaleAnimation);
 
 AlphaAnimation alphaAnimation = new AlphaAnimation(0.5f,1.0f);
 alphaAnimation.setDuration(3 * 1000L);
 alphaAnimation.setFillAfter(true);
 binding.ivSlogan.setAnimation(alphaAnimation);
 
 | 
| <androidx.constraintlayout.widget.ConstraintLayout 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:context=".SplashActivity">
 
 <ImageView
 android:id="@+id/imageView"
 android:background="@drawable/bg_splash"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:contentDescription="@string/app_name" />
 
 <TextView
 android:id="@+id/slogan_bottom"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginBottom="44dp"
 android:text="@string/slogan_txt"
 android:textColor="@color/white"
 android:textSize="18sp"
 app:layout_constraintBottom_toBottomOf="parent"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintStart_toStartOf="parent" />
 
 <TextView
 android:id="@+id/slogan_top"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginBottom="30dp"
 android:text="@string/slogan_top_text"
 android:textColor="@color/white"
 android:textSize="18sp"
 app:layout_constraintBottom_toTopOf="@+id/slogan_bottom"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintStart_toStartOf="parent" />
 
 <ImageView
 android:id="@+id/ivSlogan"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginBottom="80dp"
 app:layout_constraintBottom_toBottomOf="parent"
 app:layout_constraintEnd_toEndOf="parent"
 app:layout_constraintStart_toStartOf="parent"
 app:layout_constraintTop_toTopOf="parent"
 app:srcCompat="@drawable/ic_logo_slogan" />
 
 </androidx.constraintlayout.widget.ConstraintLayout>
 
 | 
动画效果

4.2 Loading动画效果
| RotateAnimation rotateAnimation = new RotateAnimation(0,360f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
 rotateAnimation.setDuration(1500);
 rotateAnimation.setRepeatCount(-1);
 rotateAnimation.setRepeatMode(Animation.RESTART);
 rotateAnimation.setInterpolator(new LinearInterpolator());
 
 | 
4.3 扫描动画
动画文件
| <?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"
 android:duration="3000">
 <scale
 android:fromXScale="1.0"
 android:fromYScale="1.0"
 android:pivotX="50%"
 android:pivotY="50%"
 android:repeatCount="infinite"
 android:toXScale="3.0"
 android:toYScale="3.0" />
 <alpha
 android:fromAlpha="0.4"
 android:repeatCount="infinite"
 android:toAlpha="0.0" />
 </set>
 
 | 
| Animation animationSet1 = getScanAnimation();Animation animationSet2 = getScanAnimation();
 animationSet2.setStartOffset(750);
 Animation animationSet3 = getScanAnimation();
 animationSet3.setStartOffset(1500);
 Animation animationSet4 = getScanAnimation();
 animationSet4.setStartOffset(2250);
 
 binding.startScan.setOnClickListener(view -> {
 binding.circle1.startAnimation(animationSet1);
 binding.circle2.startAnimation(animationSet2);
 binding.circle3.startAnimation(animationSet3);
 binding.circle4.startAnimation(animationSet4);
 });
 
 private Animation getScanAnimation(){
 return AnimationUtils.loadAnimation(this,R.anim.scan_anim);
 }
 
 | 
五、逐帧动画
示例:
在res/Drawable文件下新建动画文件:
| <?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android"
 android:oneshot="false">
 <item
 android:drawable="@drawable/a1"
 android:duration="80" />
 <item
 android:drawable="@drawable/a2"
 android:duration="80" />
 <item
 android:drawable="@drawable/a3"
 android:duration="80" />
 </animation-list>
 
 | 
在代码中使用:
| AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getBackground();animationDrawable.start();
 
 | 
android:oneshot 如果是false,表示无限循环,true表示只展示一次
5.1 AnimationDrawable类
在Android中,逐帧动画需要得到AnimationDrawable类的支持,它位于android.graphics.drawable包下,是Drawable的间接子类。它主要用来创建一个逐帧动画,并且可以对帧进行拉伸,把它设置为View的背景。
AnimationDrawable的常用函数:
| void start() void stop()
 int getDuration(int i)
 int getNumberOfFrames()
 Drawable getFrame(int index)
 boolean isRunning()
 void setOneShot(boolean oneShot)
 boolean isOneShot()
 void addFrame(@NonNull Drawable frame, int duration)
 
 |