动画类型
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)
|