篇幅比较长,耐心点看,总结了Android中有关动画的细节,包括一些使用的小例子。
源码地址:
https://github.com/StarsAaron/AnimationTestDemo/tree/master

动画

1. View Animation 视图动画

1.1 Frame Animation 帧动画

使用方法:
使用时需要在res下的drawable文件夹中放入需要动画显示的图片,同时在该文件夹中新建一个xml文件。

anim_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="@drawable/frame1"android:duration="500"/>
<item android:drawable="@drawable/frame2"android:duration="500"/>
<item android:drawable="@drawable/frame3"android:duration="500"/>
<item android:drawable="@drawable/frame4"android:duration="500"/>
<item android:drawable="@drawable/frame5"android:duration="500"/>
</animation-list>

给控件设置动画:

image.setBackgroundResource(R.drawable.anim_list);

开启动画:

AnimationDrawable animation_drawable = (AnimationDrawable)image.getBackground();
animation_drawable.start();

停止动画:

animation_drawable.stop();

1.2 Tween Animation 补间动画

知识点:
1) 四种类型动画:alphascaletranslaterotate 的xml文件和代码定义方式。
2) Interpolator 插补器使用
3) set 动画组合

注意:动作定义文件应该存放在res/anim文件夹下,访问时采用R.anim.XXX.xml的方式

Android 使用 Animation 代表抽象的动画类,它包括如下几个子类:

  • AlphaAnimation :透明度改变的动画。需指定动画起、止的透明度(0~1)及持续时间。
  • ScaleAnimation :大小缩放的动画。需指定动画起、止的缩放比(X、Y 轴向缩放参数)及持续时间。还应通过 pivotX、pivotY 指定缩放中心的坐标。
  • TranslateAnimation :位移变化的动画。需指定动画起、止的位置(X、Y 坐标)及持续时间。
  • RotateAnimation :旋转动画。需指定动画起、止的旋转角度(X、Y 轴向缩放参数)及持续时间。还应通过 pivotX、pivotY 指定旋转轴心的坐标。

一旦在程序中通过 AnimationUtils 得到代表补间动画的 Animation 之后,即可调用 View 的如下方法开始对该 View 执行动画。

startAnimation(Animation anim);

Animation类是所有动画(scale、alpha、translate、rotate)的基类。

它所具有的标签及对应函数为:

xml属性 代码方法 描述
android:duration setDuration(long) 动画持续时间,以毫秒为单位
android:fillAfter setFillAfter(boolean) 如果设置为true,控件动画结束时,将保持动画最后时的状态
android:fillBefore setFillBefore(boolean) 如果设置为true,控件动画结束时,还原到开始动画前的状态
android:fillEnabled setFillEnabled(boolean) 与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态
android:repeatCount setRepeatCount(int) 重复次数
android:repeatMode setRepeatMode(int) 重复类型,有reverse和restart两个值,取值为RESTART或 REVERSE,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。
android:interpolator setInterpolator(Interpolator) 设定插值器,其实就是指定的动作效果,比如弹跳效果等

1.2.1 四种变化

1) alpha透明度

xml中定义

alpha标签——调节透明度
1. 自身属性

  • android:fromAlpha 动画开始的透明度,从0.0 –1.0 ,0.0表示全透明,1.0表示完全不透明
  • android:toAlpha 动画结束时的透明度,也是从0.0 –1.0 ,0.0表示全透明,1.0表示完全不透明

2. 从Animation类继承的属性

注意:动作定义文件应该存放在res/anim文件夹下,访问时采用R.anim.XXX.xml的方式

例子:tween_alphaanim.xml

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"android:duration="3000"android:fillBefore="true"android:fromAlpha="1.0"android:toAlpha="0.1">
</alpha><!-- 透明度控制动画效果 alpha浮点型值:fromAlpha 属性为动画起始时透明度toAlpha   属性为动画结束时透明度说明:0.0表示完全透明1.0表示完全不透明以上值取0.0-1.0之间的float数据类型的数字长整型值:duration  属性为动画持续时间说明:时间以毫秒为单位-->

控件使用动画:

// 透明度
Animation alpaAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_alphaanim);
view.startAnimation(alpaAnimation);

代码中定义AlphaAnimation

对应的构造函数为:

AlphaAnimation(Context context, AttributeSet attrs) 同样,从本地XML加载动画,基本不用
AlphaAnimation(float fromAlpha, float toAlpha)

例子:

// 定义透明度动画
AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.1f);
alphaAnim.setDuration(3000);
alphaAnim.setFillBefore(true);
// 使用动画
view.startAnimation(alphaAnim);

2) scale 缩放

scale标签——调节尺寸

1. 自有属性

  • android:fromXScale 起始的X方向上相对自身的缩放比例,浮点值,比如1.0代表自身无变化,0.5代表起始时缩小一倍,2.0代表放大一倍;
  • android:toXScale 结尾的X方向上相对自身的缩放比例,浮点值;
  • android:fromYScale 起始的Y方向上相对自身的缩放比例,浮点值,
  • android:toYScale 结尾的Y方向上相对自身的缩放比例,浮点值;
  • android:pivotX 缩放起点X轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,当为数值时,表示在当前View的左上角,即原点处加上50px,做为起始缩放点;如果是50%,表示在当前控件的左上角加上自己宽度的50%做为起始点;如果是50%p,那么就是表示在当前的左上角加上父控件宽度的50%做为起始点x轴坐标。(具体意义,后面会举例演示)
  • android:pivotY 缩放起点Y轴坐标,取值及意义跟android:pivotX一样。

2. 从Animation类继承的属性

Animation类是所有动画(scale、alpha、translate、rotate)的基类,这里以scale标签为例,讲解一下,Animation类所具有的属性及意义。关于Animation类的官方文档位置为:《Animation》

  • android:duration 动画持续时间,以毫秒为单位
  • android:fillAfter 如果设置为true,控件动画结束时,将保持动画最后时的状态
  • android:fillBefore 如果设置为true,控件动画结束时,还原到开始动画前的状态
  • android:fillEnabled 与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态
  • android:repeatCount 重复次数
  • android:repeatMode 重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。
  • android:interpolator 设定插值器,其实就是指定的动作效果,比如弹跳效果等,不在这小节中讲解,后面会单独列出一单讲解。

xml中定义

scale标签——调节尺寸

1、自有属性

scale标签是缩放动画,可以实现动态调控件尺寸的效果,有下面几个属性:
android:fromXScale 起始的X方向上相对自身的缩放比例,浮点值,比如1.0代表自身无变化,0.5代表起始时缩小一倍,2.0代表放大一倍;
android:toXScale 结尾的X方向上相对自身的缩放比例,浮点值;
android:fromYScale 起始的Y方向上相对自身的缩放比例,浮点值,
android:toYScale 结尾的Y方向上相对自身的缩放比例,浮点值;
android:pivotX 缩放起点X轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,当为数值时,表示在当前View的左上角,即原点处加上50px,做为起始缩放点;如果是50%,表示在当前控件的左上角加上自己宽度的50%做为起始点;如果是50%p,那么就是表示在当前的左上角加上父控件宽度的50%做为起始点x轴坐标。(具体意义,后面会举例演示)
android:pivotY 缩放起点Y轴坐标,取值及意义跟android:pivotX一样。

2、从Animation类继承的属性

注意:动作定义文件应该存放在res/anim文件夹下,访问时采用R.anim.XXX.xml的方式

例子:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"android:duration="700"android:fillBefore="true"android:fromXScale="0.0"android:fromYScale="0.0"android:pivotX="50%"android:pivotY="50%"android:repeatCount="1"android:repeatMode="restart"android:toXScale="1.4"android:toYScale="1.4"/><!-- Animation变化坐标点的参照类型上面看到,RotateAnimation、ScaleAnimation、TranslateAnimation都存在一对pivotXType,pivotYType参数,它们是用来指定点的参照类型,使用int类型以静态常量的形式定义在Animation中,它有如下个值:ABSOLUTE:以绝对坐标为参照。RELATIVE_TO_PARENT:以父容器为参照。RELATIVE_TO_SELF:以当前容器为参照。细心的朋友有发现到,在使用XML定义动画资源的时候,没有关于pivotXType、pivotYType两个属性,其实它们结合到了设定点的坐标中中,以 pivotXValue、pivotYValue两个属性替代,其中如果需要设定为父容器为参照,需要在属性值后面加"p"即可。 --><!-- 尺寸伸缩动画效果 scale属性:interpolator 指定一个动画的插入器在我试验过程中,使用android.res.anim中的资源时候发现有三种动画插入器:accelerate_decelerate_interpolator  加速-减速 动画插入器accelerate_interpolator           加速-动画插入器decelerate_interpolator           减速- 动画插入器其他的属于特定的动画效果浮点型值:fromXScale 属性为动画起始时 X坐标上的伸缩尺寸    toXScale   属性为动画结束时 X坐标上的伸缩尺寸     fromYScale 属性为动画起始时Y坐标上的伸缩尺寸    toYScale   属性为动画结束时Y坐标上的伸缩尺寸    说明:以上四种属性值    0.0表示收缩到没有 1.0表示正常无伸缩     值小于1.0表示收缩  值大于1.0表示放大pivotX     属性为动画相对于物件的X坐标的开始位置(坐标原点X点坐标)pivotY     属性为动画相对于物件的Y坐标的开始位置(坐标原点Y点坐标)说明:以上两个属性值 从0%-100%中取值50%为物件的X或Y方向坐标上的中点位置长整型值:duration  属性为动画持续时间说明:   时间以毫秒为单位布尔型值:fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用-->tween_alphaanim.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"android:duration="3000"android:fillBefore="true"android:fromAlpha="1.0"android:toAlpha="0.1">
</alpha><!-- 透明度控制动画效果 alpha浮点型值:fromAlpha 属性为动画起始时透明度toAlpha   属性为动画结束时透明度说明:0.0表示完全透明1.0表示完全不透明以上值取0.0-1.0之间的float数据类型的数字长整型值:duration  属性为动画持续时间说明:时间以毫秒为单位-->

控件使用动画:

// 缩放
Animation scaleAnimation= AnimationUtils.loadAnimation(this, R.anim.tween_scaleanim);
view.startAnimation(scaleAnimation);

代码中定义ScaleAnimation

ScaleAnimation有下面几个构造函数:
- ScaleAnimation(Context context, AttributeSet attrs) 从XML文件加载动画,基本用不到
- ScaleAnimation(float fromX, float toX, float fromY, float toY)
- ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)
- ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

第一个构造函数是从本地XML文件加载动画,基本用不到的,我们主要看下面三个构造函数。

在标签属性android:pivotX中有三种取值,数,百分数,百分数p;体现在构造函数中,就是最后一个构造函数的pivotXType,它的取值有三个:
- Animation.ABSOLUTE
- Animation.RELATIVE_TO_SELF
- Animation.RELATIVE_TO_PARENT

例子:

// 伸缩动画
Animation scaleAnim = new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnim.setDuration(700);
// 使用动画
view.startAnimation(scaleAnim);

3) rotate旋转

rotate标签——旋转

1. 自身属性
- android:fromDegrees 开始旋转的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数
- android:toDegrees 结束时旋转到的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数
- android:pivotX 缩放起点X轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,具体意义已在scale标签中讲述,这里就不再重讲
- android:pivotY 缩放起点Y轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p

2. 从Animation类继承的属性
- android:duration 动画持续时间,以毫秒为单位
- android:fillAfter 如果设置为true,控件动画结束时,将保持动画最后时的状态
- android:fillBefore 如果设置为true,控件动画结束时,还原到开始动画前的状态
- android:fillEnabled 与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态
- android:repeatCount 重复次数
- android:repeatMode 重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。
- android:interpolator 设定插值器,其实就是指定的动作效果,比如弹跳效果等,不在这小节中讲解,后面会单独列出一单讲解。

xml中定义

rotate标签——旋转

1. 自身属性

  • android:fromDegrees 开始旋转的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数
  • android:toDegrees 结束时旋转到的角度位置,正值代表顺时针方向度数,负值代码逆时针方向度数
  • android:pivotX 缩放起点X轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,具体意义已在scale标签中讲述,这里就不再重讲
  • android:pivotY 缩放起点Y轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p

2. 从Animation类继承的属性

注意:动作定义文件应该存放在res/anim文件夹下,访问时采用R.anim.XXX.xml的方式

例子:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"android:duration="3000"android:fillAfter="true"android:fromDegrees="0"android:pivotX="50%"android:pivotY="50%"android:toDegrees="650">
</rotate><!-- rotate 旋转动画效果属性:interpolator 指定一个动画的插入器在我试验过程中,使用android.res.anim中的资源时候发现有三种动画插入器:accelerate_decelerate_interpolator     加速-减速 动画插入器accelerate_interpolator                加速-动画插入器decelerate_interpolator                减速- 动画插入器其他的属于特定的动画效果浮点数型值:fromDegrees 属性为动画起始时物件的角度    toDegrees   属性为动画结束时物件旋转的角度 可以大于360度   说明:当角度为负数——表示逆时针旋转当角度为正数——表示顺时针旋转              (负数from——to正数:顺时针旋转)   (负数from——to负数:逆时针旋转) (正数from——to正数:顺时针旋转) (正数from——to负数:逆时针旋转)       pivotX     属性为动画相对于物件的X坐标的开始位置pivotY     属性为动画相对于物件的Y坐标的开始位置说明:        以上两个属性值 从0%-100%中取值50%为物件的X或Y方向坐标上的中点位置长整型值:duration  属性为动画持续时间说明:       时间以毫秒为单位-->

控件使用动画:

// 旋转
Animation rotateAnimation= AnimationUtils.loadAnimation(this, R.anim.tween_rotateanim);
view.startAnimation(rotateAnimation);

代码中定义RotateAnimation

对应的构造函数有:

  • RotateAnimation(Context context, AttributeSet attrs)  从本地XML文档加载动画,同样,基本不用
    RotateAnimation(float fromDegrees, float toDegrees)
  • RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
  • RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)

RotateAnimation跟ScaleAnimation差不多,关键问题同样是pivotXType和pivotYType的选择,同样有三个取值:Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF和Animation.RELATIVE_TO_PARENT;

例子:

// 旋转动画
Animation rotateAnim = new RotateAnimation(0, -650, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnim.setDuration(3000);
rotateAnim.setFillAfter(true);
// 使用动画
view.startAnimation(rotateAnim);

4) translate平移

translate标签 —— 平移

1. 自身属性

  • android:fromXDelta 起始点X轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,具体意义已在scale标签中讲述,这里就不再重讲
  • android:fromYDelta 起始点Y轴从标,可以是数值、百分数、百分数p 三种样式;
  • android:toXDelta 结束点X轴坐标
  • android:toYDelta 结束点Y轴坐标

2. 从Animation类继承的属性

  • android:duration 动画持续时间,以毫秒为单位
  • android:fillAfter 如果设置为true,控件动画结束时,将保持动画最后时的状态
  • android:fillBefore 如果设置为true,控件动画结束时,还原到开始动画前的状态
  • android:fillEnabled 与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态
  • android:repeatCount 重复次数
  • android:repeatMode 重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。
  • android:interpolator 设定插值器,其实就是指定的动作效果,比如弹跳效果等,不在这小节中讲解,后面会单独列出一单讲解。

xml中定义

translate标签 —— 平移

1. 自身属性

  • android:fromXDelta 起始点X轴坐标,可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,具体意义已在scale标签中讲述,这里就不再重讲
  • android:fromYDelta 起始点Y轴从标,可以是数值、百分数、百分数p 三种样式;
  • android:toXDelta 结束点X轴坐标
  • android:toYDelta 结束点Y轴坐标

2. 从Animation类继承的属性

  • android:duration 动画持续时间,以毫秒为单位
  • android:fillAfter 如果设置为true,控件动画结束时,将保持动画最后时的状态
  • android:fillBefore 如果设置为true,控件动画结束时,还原到开始动画前的状态
  • android:fillEnabled 与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态
  • android:repeatCount 重复次数
  • android:repeatMode 重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。
  • android:interpolator 设定插值器,其实就是指定的动作效果,比如弹跳效果等,不在这小节中讲解,后面会单独列出一单讲解。

例子:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"android:duration="2000"android:fillBefore="true"android:fromXDelta="0"android:fromYDelta="0"android:toXDelta="-80"android:toYDelta="-80">
</translate><!-- translate 位置转移动画效果整型值:fromXDelta 属性为动画起始时 X坐标上的位置toXDelta   属性为动画结束时 X坐标上的位置fromYDelta 属性为动画起始时 Y坐标上的位置toYDelta   属性为动画结束时 Y坐标上的位置注意:没有指定fromXType toXType fromYType toYType 时候,默认是以自己为相对参照物长整型值:duration  属性为动画持续时间说明:   时间以毫秒为单位--><!-- AnimationSet: http://developer.android.com/reference/android/view/animation/AnimationSet.html-->

控件使用动画:

// 平移
Animation translateAnimation= AnimationUtils.loadAnimation(this, R.anim.tween_translateanim);
view.startAnimation(translateAnimation);

代码中定义TranslateAnimation

对应的构造函数为:

  • TranslateAnimation(Context context, AttributeSet attrs) 同样,基本不用
  • TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
  • TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)

由于fromXDelta、fromYDelta、toXDelta、toYDelta这三个属性都具有三种状态,所以在构造函数中,最理想的状态就是第三个构造函数,能够指定每个值的类型,第二个构造函数:TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)使用是绝对数值。只有最后一个构造函数可以指定百分数和相对父控件的百分数。

例子:

// 平移动画
Animation translateAnim = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -80,
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -80);
translateAnim.setDuration(2000);
translateAnim.setFillBefore(true);
// 使用动画
view.startAnimation(translateAnim);

AnimatiorSet组合

xml中定义

set标签——定义动作合集
Set标签就可以将几个不同的动作定义成一个组;set标签自已是没有属性的,他的属性都是从Animation继承而来,但当它们用于Set标签时,就会对Set标签下的所有子控件都产生作用。

属性有:(从Animation类继承的属性)

例子:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:duration="3000"android:fillAfter="true"><alphaandroid:fromAlpha="0.0"android:toAlpha="1.0"/><scaleandroid:fromXScale="0.0"android:fromYScale="0.0"android:pivotX="50%"android:pivotY="50%"android:toXScale="1.4"android:toYScale="1.4"/><rotateandroid:fromDegrees="0"android:pivotX="50%"android:pivotY="50%"android:toDegrees="720"/>
</set><!-- 透明度控制动画效果 alpha浮点型值:fromAlpha 属性为动画起始时透明度toAlpha   属性为动画结束时透明度说明:0.0表示完全透明1.0表示完全不透明以上值取0.0-1.0之间的float数据类型的数字长整型值:duration  属性为动画持续时间说明:时间以毫秒为单位-->

控件使用动画:

// 动画集
Animation setAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_setanim);
view.startAnimation(setAnimation); 

代码中定义

  • AnimationSet(Context context, AttributeSet attrs) 同样,基本不用
  • AnimationSet(boolean shareInterpolator) shareInterpolator取值true或false,取true时,指在AnimationSet中定义一个插值器(interpolater),它下面的所有动画共同。如果设为false,则表示它下面的动画自己定义各自的插值器。

例子:

// 组合动画
AnimationSet setAnim = new AnimationSet(true);
setAnim.addAnimation(alphaAnim);
setAnim.addAnimation(scaleAnim);
setAnim.addAnimation(rotateAnim);
setAnim.setFillAfter(true);
// 使用动画
view.startAnimation(setAnim);

Interpolator插值器

Interpolator属性是Animation类的一个XML属性,所以alpha、scale、rotate、translate、set都会继承得到这个属性。

InterPolator 根据特定算法计算出整个动画所需动态插入帧的密度和位置。
它是一个接口,定义了所有 Interpolator 都需要实现的方法:
float getInterpolation(float input)
开发者可通过实现 Interpolator 来控制动画的变化速度。

插值器类:

类名 描述
AccelerateDecelerateInterpolator 在动画开始与介绍的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后然后向前甩
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator 动画结束的时候弹起
CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的地方快然后慢
LinearInterpolator 以常量速率改变
OvershootInterpolator 向前甩一定值后再回到原来位置

xml中定义

为了在动画资源文件中指定补间动画所使用的 Interpolator,定义动画的元素 <set.../><alpha.../><scale.../><translate.../><rotate.../> 都可指定一个 android:interpolator 属性以指定动画的变化速度。Android 系统的 R.anim 类中包含了大致常量,它们定义了不同的动画速度。如:

  • @android:linear_interpolator :匀速变换
  • @android:accelerate_interpolator :加速变换
  • @android:decelerate_interpolator :减速变换

    注:上述常量的写法规律,其实是把系统提供的 Interpolator 实现类的类名的驼峰写法改为下划线写法即可。

例子:

scale标签

先看下XML代码:(从控件中心点,从0放大到1.4倍,保持结束时的状态)

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:fromXScale="0.0"android:toXScale="1.4"android:fromYScale="0.0"android:toYScale="1.4"android:pivotX="50%"android:pivotY="50%"android:duration="700"android:fillAfter="true"
/>

rotate标签
先看下XML代码:(从控件中心点,从0放大到1.4倍,保持结束时的状态)

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:fromDegrees="0"android:toDegrees="360"android:pivotX="50%"android:pivotY="50%android:duration="700"android:fillAfter="true"
/>

alpha标签
将透明度从0变成1.0,使用不同的插值器看看有什么不同(因为只是透明度的变化,所以基本看不出来有什么不同)

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:fromAlpha="0.0"android:toAlpha="1.0"android:duration="3000"android:fillAfter="true"
/>

translate标签

把控件从(0,0)平移到(-200,-200)的位置,保持结束时状态不变,使用不同插值器。

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/accelerate_decelerate_interpolator"android:fromXDelta="0"android:toXDelta="-200"android:fromYDelta="0"android:toYDelta="-200"android:duration="2000"android:fillAfter="true"
/>

代码中定义

Android 为 Interpolator 提供了如下几个实现类:

  • LinearInterpolator :动画以匀速改变。
  • AccelerateInterpolator :动画以匀加速改变。
  • AccelerateDecelerateInterpolator :动画的改变以匀加速开始,以匀减速结束,中间改变最快。
  • CycleInterpolator :动画循环播放特定的次数,变化速度按正统曲线改变。
  • DecelerateInterpolator :动画以匀减速改变。

例子:

// 插播器动画
Animation interpolateScaleAnim = new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
interpolateScaleAnim.setInterpolator(new BounceInterpolator());
interpolateScaleAnim.setDuration(3000);// 使用动画
view.startAnimation(interpolateScaleAnim ); 

动画监听

AnimationSet as=new AnimationSet(true);
RotateAnimation al=new RotateAnimation(0,-720,Animation.RELATIVE_TO_PARENT
,0.5f,Animation.RELATIVE_TO_PARENT,0.5f);
al.setDuration(3000);
al.setAnimationListener(new AnimationListener() {public void onAnimationStart(Animation animation) {}public void onAnimationEnd(Animation animation) {}public void onAnimationRepeat(Animation animation) {}
});
as.addAnimation(al);
iv.startAnimation(as);

2. Property Animation属性动画

从某种角度看,属性动画是增强版的补间动画,其强大体现在两方面:

  • 补间动画只能定义两个关键帧在透明度、旋转、倾斜、位移这4个方面的变化,而属性动画可以定义任何属性的变化。
  • 补间动画只能对 UI 组件执行动画,而属性动画几乎可以对任何对象执行动画。

属性动画也需要定义如下几方面属性:

  • android:duration :动画持续时间。默认值 300 毫秒。
  • android:interpolator :动画插值方式。与补间动画中插值属性作用类似。
  • android:repeatCount :动画重复次数。
  • android:repeatMode :重复方式。指定动画结束后,从头重播还是反向播放。

2.1 两种属性动画

1) ValueAnimator

可按如下4个步骤:

  • 调用 ValueAnimator 的 ofInt()、ofFloat() 或 ofObject() 静态方法创建 ValueAnimator 实例。
  • 调用 ValueAnimator 的 setXxx() 设置动画持续时间、插值方式、重复次数等。
  • 调用 ValueAnimator 的 start() 方法启动动画。

为 ValueAnimator 注册 AnimatorUpdateListener 监听器,用以监听 ValueAnimator 计算出来的值的改变(可通过 getAnimatedValue() 方法获取当前帧的值),并将这些值应用到指定对象。

例子:

ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight - mBlueBall.getHeight());
animator.setTarget(mBlueBall);
animator.setDuration(1000).start();
// animator.setInterpolator(value)
animator.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {view.setTranslationY((Float) animation.getAnimatedValue());}
});

2) ObjectAnimator

ObjectAnimator 可直接将 ValueAnimator 在动画过程中计算出来的值应用到指定对象的指定属性上,不需要注册监听器。
使用 ObjectAnimator 的 ofInt()、ofFloat() 或 ofObject() 静态方法创建 ValueAnimator 实例时需要指定具体的对象及其属性名。

使用 ObjectAnimator 需注意:

  • 须为该对象对应的属性提供 setter 方法,例如 setAlpha(float value) 方法。
  • 调用 ObjectAnimator 的 ofInt()、ofFloat() 或 ofObject() 工厂方法时 values… 参数只提供了一个结束值。因而该对象应为该属性提供一个 getter 方法以返回一个开始值。

如果动画的对象是 View,为了能显示动画效果,可能还需在 onAnimationUpdate() 事件监听方法中调用 View.invalidate() 方法来刷新屏幕的显示。(比如对 Drawable 对象的 color 属性执行动画)。
不过 View 定义的 setter 方法(如 setAlpha()、setTranslationX() )都会自动调用 invalidate() 方法了。

代码定义例子:

ObjectAnimator anim = ObjectAnimator
.ofFloat(view, "zhy", 1.0F, 0.2F)
.setDuration(500);
anim.start();anim.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {float cVal = (Float) animation.getAnimatedValue();view.setAlpha(cVal);view.setScaleX(cVal);view.setScaleY(cVal);}
});

XML定义例子:

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"android:duration="1000"android:propertyName="scaleX"android:valueFrom="1.0"android:valueTo="2.0"android:valueType="floatType" >
</objectAnimator>

调用:

// 加载动画
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scalex);
anim.setTarget(view);
anim.start();

2.2 AnimatorSet组合动画

使用set标签,有一个orderring属性

值:

  • together 同时播放
  • sequentially 表示一个接一个执行

Xml例子:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:ordering="together" ><objectAnimatorandroid:duration="1000"android:propertyName="scaleX"android:valueFrom="1"android:valueTo="0.5" ></objectAnimator><objectAnimatorandroid:duration="1000"android:propertyName="scaleY"android:valueFrom="1"android:valueTo="0.5" ></objectAnimator>
</set>// 加载动画
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);
mMv.setPivotX(0);
mMv.setPivotY(0);
//显式的调用invalidate
mMv.invalidate();
anim.setTarget(mMv);
anim.start();

代码例子:

public void togetherRun(View view) {ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX",1.0f, 2f);ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY",1.0f, 2f);AnimatorSet animSet = new AnimatorSet();animSet.setDuration(2000);animSet.setInterpolator(new LinearInterpolator());//两个动画同时执行animSet.playTogether(anim1, anim2);
//animSet.playSequentially(items)animSet.start();
}public void playWithAfter(View view) {float cx = mBlueBall.getX();ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX",1.0f, 2f);ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY",1.0f, 2f);ObjectAnimator anim3 = ObjectAnimator.ofFloat(mBlueBall,"x", cx, 0f);ObjectAnimator anim4 = ObjectAnimator.ofFloat(mBlueBall,"x", cx);/*** anim1,anim2,anim3同时执行* anim4接着执行*/AnimatorSet animSet = new AnimatorSet();animSet.play(anim1).with(anim2);animSet.play(anim2).with(anim3);animSet.play(anim4).after(anim3);animSet.setDuration(1000);animSet.start();
}

2.3 使用PropertyValuesHolder 创建实例

ValueAnimator和ObjectAnimator除了通过ofInt(),ofFloat(),ofObject()创建实例外,还都有一个ofPropertyValuesHolder()方法来创建实例。

PropertyValuesHolder中有很多函数,有些函数的api等级是11,有些函数的api等级是14和21;

PropertyValuesHolder这个类可以先将动画属性和值暂时的存储起来,后一起执行,在有些时候可以使用替换掉AnimatorSet,减少代码量。

四个构造方法:

  • public static PropertyValuesHolder ofFloat(String propertyName, float… values)
  • public static PropertyValuesHolder ofInt(String propertyName, int… values)
  • public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,Object… values)
  • public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe… values)

KeyFrame关键帧 ,一个关键帧必须包含两个原素,第一时间点,第二位置。

构造方法:

/*** ofFloat*/
public static Keyframe ofFloat(float fraction)
public static Keyframe ofFloat(float fraction, float value)
/*** ofInt*/
public static Keyframe ofInt(float fraction)
public static Keyframe ofInt(float fraction, int value)

例子:

//keyframe
Keyframe keyframe1 = Keyframe.ofFloat(0.0f,0);
Keyframe keyframe2 = Keyframe.ofFloat(0.25f,-30);
Keyframe keyframe3 = Keyframe.ofFloat(0.5f,0);
Keyframe keyframe4 = Keyframe.ofFloat(0.75f, 30);
Keyframe keyframe5 = Keyframe.ofFloat(1.0f,0);
PropertyValuesHolder rotation = PropertyValuesHolder.ofKeyframe("rotation", keyframe1, keyframe2, keyframe3, keyframe4,keyframe5);PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha",1.0f,0.2f,1.0f);
PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX",1.0f,0.2f,1.0f);
PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY",1.0f,0.2f,1.0f);
PropertyValuesHolder color = PropertyValuesHolder.ofInt("BackgroundColor", 0XFFFFFF00, 0XFF0000FF);ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mButton, alpha, scaleX, scaleY,color,rotation);
animator.setInterpolator(new OvershootInterpolator());
animator.setDuration(5000).start();

2.4 3.0后View的自带的动画方法

在SDK11的时候,给View添加了animate方法,更加方便的实现动画效果。
在SDK12,SDK16又分别添加了withStartAction和withEndAction用于在动画前,和动画后执行一些操作。当然也可以.setListener(listener)等操作。

// need API 12
mBlueBall.animate().alpha(0).y(mScreenHeight / 2).setDuration(1000)// need API 12.withStartAction(new Runnable() {@Overridepublic void run() {Log.e(TAG, "START");}})// need API 16.withEndAction(new Runnable() {@Overridepublic void run() {Log.e(TAG, "END");runOnUiThread(new Runnable() {@Overridepublic void run() {mBlueBall.setY(0);mBlueBall.setAlpha(1.0f);}})// 等同上面使用的withEndAction和withStartAction.setListener(new Animator.AnimatorListener() {@Overridepublic void onAnimationStart(Animator animation) { }@Overridepublic void onAnimationEnd(Animator animation) { }@Overridepublic void onAnimationCancel(Animator animation) { }@Overridepublic void onAnimationRepeat(Animator animation) { }
}).start();

2.5 LayoutAnimator布局动画

布局动画:接下来看看布局动画,主要是针对viewGroup显示子view比如添加删除或显示子view时以什么动画过渡平滑的显示

主要用到两个类,LayoutAnimatorLayoutTransition

(1)LayoutAnimator设置可控制viewGroup显示子view时以什么样的动画显示平滑出来,但无法控制添加删除子view时仅仅这个子view的动画,这时就要用到(2)

(2)LayoutTransition:可控制子view添加删除时 这个子view平滑过渡的显示

LayoutAnimator

所谓的布局动画是指作用的ViewGroup上,给ViewGroup增加子View时添加一个动画过度效果。
在ViewGroup的xml中添加和这个属性:
android:animateLayoutChanges=”true”

这个效果是android默认的显示的过度效果,我们无法自定义,需要自在定义的过度效果则需要使用LayoutAnimationController类来自定义一个。

代码写法:

/*** 设置viewGroup加载子view控件显示时的过载动画,就是以什么方式显示比如旋转、平移、淡化等等* 但是动态添加删除一个view这个不生效,这时就用到LayoutTranstion了* 第一个参数:需要作用的时间* 第二个参数:每个子view显示的delay时间* setOrder:有三个取值* LayoutAnimationController.ORDER_NORMAL; //顺序显示* LayoutAnimationController.ORDER_REVERSE;//反显示* LayoutAnimationController.ORDER_RANDOM//随机显示*/private void initLayoutAnim() {//设置过渡动画ScaleAnimation sa = new ScaleAnimation(0, 1, 0, 1);//根据具体需求具体定义,也支持集合动画
//        AlphaAnimation
//        RotateAnimation
//        ScaleAnimation
//        AnimationSetsa.setDuration(800);//动画执行时长//设置动画显示的属性,0.5f是子view间隔显示时的一个延时偏移量单位是s,默认也是0.5f//即控件动画执行起始的时间间隔了0.5sLayoutAnimationController lac = new LayoutAnimationController(sa, 0.5f);//按顺序显示,其它两种可查看注释lac.setOrder(LayoutAnimationController.ORDER_RANDOM);//随机llAddViewContainer.setLayoutAnimation(lac);}

xml 写法:

<layoutAnimationxmlns:android="xxx"android:delay="0.5"android:animationOrder="normal"android:animation="anim/anim_item">

LayoutTransition

过渡的类型一共有四种:

  • LayoutTransition.APPEARING 当一个View在ViewGroup中出现时,对此View设置的动画
  • LayoutTransition.CHANGE_APPEARING 当一个View在ViewGroup中出现时,对此View对其他View位置造成影响,对其他View设置的动画
  • LayoutTransition.DISAPPEARING 当一个View在ViewGroup中消失时,对此View设置的动画
  • LayoutTransition.CHANGE_DISAPPEARING 当一个View在ViewGroup中消失时,对此View对其他View位置造成影响,对其他View设置的动画
  • LayoutTransition.CHANGE 不是由于View出现或消失造成对其他View位置造成影响,然后对其他View设置的动画。

注意:动画到底设置在谁身上,此View还是其他View。

LayoutTransition mTransition = new LayoutTransition();
transition.setAnimator(LayoutTransition.CHANGE_APPEARING,
transition.setAnimator(LayoutTransition.CHANGE_APPEARING));
transition.setAnimator(LayoutTransition.APPEARING,null);
transition.setAnimator(LayoutTransition.DISAPPEARING,null);
transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,null);使用布局动画:
// 创建一个GridLayout
mGridLayout = new GridLayout(this);
// 设置每列5个按钮
mGridLayout.setColumnCount(5);
// 添加到布局中
viewGroup.addView(mGridLayout);
//设置动画
mGridLayout.setLayoutTransition(mTransition);

复杂例子:

    /*** 动态添加删除一个view时,view显示的过渡动画效果* ViewGroup中Layout的动画实现* 调用 LayoutTransition 对象的 setAnimator() 方法来定义下列动画方式,调用参数是 Animator* 对象和以下 LayoutTransition 常量:* (1)APPEARING —— 元素在容器中显现时需要动画显示。* (2)CHANGE_APPEARING —— 由于容器中要显现一个新的元素,其它元素的变化需要动画显示。* (3)DISAPPEARING —— 元素在容器中消失时需要动画显示。* (4)CHANGE_DISAPPEARING —— 由于容器中某个元素要消失,其它元素的变化需要动画显示。*/private void initLayoutTransition() {  mTransitioner = new LayoutTransition();  llAddViewContainer.setLayoutTransition(mTransitioner);//view出现时 view自身的动画效果ObjectAnimator animator1 = ObjectAnimator.ofFloat(null, "rotationY", 90F, 0F).setDuration(mTransitioner.getDuration(LayoutTransition.APPEARING));mTransitioner.setAnimator(LayoutTransition.APPEARING, animator1);//view 消失时,view自身的动画效果ObjectAnimator animator2 = ObjectAnimator.ofFloat(null, "rotationX", 0F, 90F, 0F).setDuration(mTransitioner.getDuration(LayoutTransition.DISAPPEARING));mTransitioner.setAnimator(LayoutTransition.DISAPPEARING, animator2);//view 动画改变时,布局中的每个子view动画的时间间隔mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);mTransitioner.setStagger(LayoutTransition.CHANGE_DISAPPEARING, 30);//为什么这里要这么写?具体我也不清楚,ViewGroup源码里面是这么写的,我只是模仿而已 不这么写貌似就没有动画效果了,所以你懂的!//view出现时,导致整个布局改变的动画PropertyValuesHolder pvhLeft =PropertyValuesHolder.ofInt("left", 0, 1);PropertyValuesHolder pvhTop =PropertyValuesHolder.ofInt("top", 0, 1);PropertyValuesHolder pvhRight =PropertyValuesHolder.ofInt("right", 0, 1);PropertyValuesHolder pvhBottom =PropertyValuesHolder.ofInt("bottom", 0, 1);PropertyValuesHolder animator3 = PropertyValuesHolder.ofFloat("scaleX", 1F, 2F, 1F);final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder(this, pvhLeft, pvhTop, pvhRight, pvhBottom, animator3).setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_APPEARING));changeIn.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {View view = (View) ((ObjectAnimator) animation).getTarget();view.setScaleX(1.0f);}});mTransitioner.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn);// view消失,导致整个布局改变时的动画  //Keyframe 对象中包含了一个时间/属性值的键值对,用于定义某个时刻的动画状态。Keyframe kf0 = Keyframe.ofFloat(0f, 0f);Keyframe kf1 = Keyframe.ofFloat(0.5f, 2f);Keyframe kf2 = Keyframe.ofFloat(1f, 0f);PropertyValuesHolder pvhRotation =PropertyValuesHolder.ofKeyframe("scaleX", kf0, kf1, kf2);final ObjectAnimator changeOut = ObjectAnimator.ofPropertyValuesHolder(this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhRotation).setDuration(mTransitioner.getDuration(LayoutTransition.CHANGE_DISAPPEARING));changeOut.addListener(new AnimatorListenerAdapter() {@Overridpublic void onAnimationEnd(Animator animation) {View view = (View) ((ObjectAnimator) animation).getTarget();view.setScaleX(1.0f);}});mTransitioner.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeOut);}

2.6 动画监听

ObjectAnimator changeIn;
changeIn.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {View view = (View) ((ObjectAnimator) animation).getTarget();view.setScaleX(1.0f);}
});

Android笔记系列--动画相关推荐

  1. Android笔记 帧动画

    <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255) ...

  2. Android笔记系列--获取手机号码

    有的手机获取不到手机号码的原因:     手机号码不是所有的都能获取.只是有一部分可以拿到.这个是由于移动运营商没有把手机号码的数据写入到sim卡中.SIM卡只有唯一的编号,供网络与设备识别那就是IM ...

  3. Android笔记系列--超详细DownloadManager使用,兼容到版本8.0

    超详细DownloadManager使用,兼容到版本8.0 最近用到了软件更新,感觉自己写更新比较麻烦,还要定义通知栏的进度效果,想了一下还是使用系统自带的DownloadManager好了,但这个坑 ...

  4. android 同根动画_android 动画系列 (1) - tween 动画(view动画)

    这是我这个系列的目录,有兴趣的可以看下: android 动画系列 - 目录 tween 动画早些时候我们也叫补间动画(我也不知道为啥),现在也有叫 view 动画的.tween动画是2.X 时代的产 ...

  5. android学习笔记---55_frame动画的实现,Java技术qq交流群:JavaDream:251572072

    android学习笔记---55_frame动画的实现,Java技术qq交流群:JavaDream:251572072 Java技术qq交流群:JavaDream:251572072 2013/5/1 ...

  6. Android实用视图动画及工具系列之三:表情加载动画和失败加载动画,人物加载动画

    实现效果 功能说明 网速慢时,加载网络数据时,界面怎么处理才美观?载入失败或网络丢包时,如何让界面显得更和谐?这一直是开发人员和美工人员不绝于耳的问题,为了达到功能和UI的完美交互,我们不得不做一些基 ...

  7. 【Android笔记25】Android中的动画效果之逐帧动画

    这篇文章,主要介绍Android中的动画效果之逐帧动画. 目录 一.逐帧动画 1.1.什么是逐帧动画 1.2.逐帧动画的使用 (1)创建drawable动画资源<

  8. Android面试系列文章2018之内存管理之UI卡顿篇

    Android面试系列文章2018之内存管理之UI卡顿篇 1.UI卡顿的原理   60ftp –> 16ms: Android系统每隔16ms都会对界面进行渲染一次,造成卡顿的原因就是Andro ...

  9. Android APK系列5-------修改APK中的内容

    Android APK系列5-------修改APK中的内容 首先我们需要下载反编译工具,apktool_gui_1.3.5这个是很好用的反编译工具,可以编译apk.dex.当然如果只是简单修改APK ...

最新文章

  1. Hibernate 配置 p6spy 显示完整 sql 语句
  2. 腾讯员工上半年人均月薪 7.8 万,网友:别人拿月薪我拿年薪。。。
  3. rethat linux安装nginx,RedHat和CentOS下Nginx安装
  4. DELL服务器安装过程中出现的ERROR及解决方案
  5. 【图像分割应用】医学图像分割(一)——脑区域分割
  6. 关于onreadystatechange属性(转)
  7. EF Code First Migrations数据库迁移
  8. 初始化模型参数 python_pytorch 网络参数 weight bias 初始化详解_python_脚本之家
  9. 韦东奕:被数学“选中”的天才
  10. Java阶段2-02JS:07JS中的事件
  11. mysql 分页 order_mysql学习笔记:九.排序和分页(order by、limit)
  12. 安卓手机内外SD卡互换
  13. 用python画股票行情图
  14. 【舍友计划】恶搞~让计算机变卡变慢
  15. 计算机分区容量计算公式,100g等于多少mb?电脑分区100g是多少mb?电脑100g内存等于多少mb?...
  16. 创建PHP测试页面,连接并查询MariaDB数据库
  17. SDU信息门户(8)组队和文件系统分析
  18. 牛客网赛码网 输入输出格式
  19. 关于雷蛇耳机麦克风突然失灵
  20. [小黄书后台]文件上传到服务器

热门文章

  1. docker Error An error occurred 引发异常的上一位置中堆栈跟踪的末尾
  2. CloudFoundry User Account and Authentication (UAA) Server Identity Provider
  3. UE4基础概念(宏标记)
  4. 51单片机实现交通信号灯
  5. 士兵突击【幕后故事】
  6. 工作上的三个境界:能做,能做好,能持续做好
  7. QT支持https及编译OpenSSL
  8. 索尼电视显示由于服务器问题,索尼电视网络出现问题加载失败怎么办,当贝市场最新解决方法!...
  9. python学习: 教你如何使用python挣零花钱
  10. 计算机二级考试中所有判断题(含答案)