Android动画机制总结笔记--补间动画TweenAnimation篇

注意:本篇文章是本人阅读关于Android动画的文章所写下的总结,方便以后查阅,所有内容非原创,侵权删。

本篇文章内容来自于

  1. Android高级进阶 顾浩鑫
  2. Android自定义控件三部曲文章索引之动画篇

目录

3.补间动画 TweenAnimation
--3.1 AlphaAnimation 透明度动画
--3.2 TranslateAnimation 位置移动动画
--3.3 RotateAnimation 旋转动画
--3.4 ScaleAnimation 缩放动画
--3.5 AnimationSet 动作合集
--3.6 插值器Interpolator
--3.7 自定义补间动画(待补)

3.补间动画 TweenAnimation

只需要定义动画的开始和结束的两个关键帧,并指定动画变化的时间和方式等,然后交由Android系统进行计算。
通过在两个关键帧之间插入渐变值来实现平滑过渡,从而对view的内容完成一系列的图形变化来实现的动画效果。

补间动画分为:scale、alpha、translate、rotate

Animation类(scale、alpha、translate、rotate)共有的属性
*   android:duration 动画持续时间,以毫秒为单位 
*   android:fillAfter 如果设置为true,控件动画结束时,将保持动画最后时的状态
*   android:fillBefore 如果设置为true,控件动画结束时,还原到开始动画前的状态
*   android:fillEnabled 与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态
*   android:repeatCount 重复次数
*   android:repeatMode 重复类型,有reverse和restart两个值,reverse表示倒序回放,restart表示重新放一遍,必须与repeatCount一起使用才能看到效果。
*   android:interpolator  设定插值器

3.1 AlphaAnimation 透明度动画

AlphaAnimation自有属性
android:fromAlpha 动画开始的透明度
从0.0-1.0,0.0表示全透明,1.0表示完全不透明
android:toAlpha 动画结束时的透明度
XML实现

1.在res/anim新建xml文件 anim_tween_alpha.xml

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:fromAlpha="0.1"
    android:toAlpha="1.0" />

2.播放动画
通过AnimationUtils.loadAnimation(this, xxx);从XML文件中获取动画。再利用startAnimation将动画传递给指定控件显示。

Animation anim_tween_alpha = AnimationUtils.loadAnimation(this, R.anim.anim_tween_alpha);
ivAnimTweenAlpha.startAnimation(anim_tween_alpha);
code实现

AlphaAnimation构造函数

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

实现代码

AlphaAnimation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);
alphaAnimation.setDuration(3000);
ivAnimTweenAlpha.startAnimation(alphaAnimation);

3.2 TranslateAnimation 位置移动动画

TranslateAnimation自身属性
android:fromXDelta 起始点X轴坐标
可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,具体意义已在scale标签中讲述
android:fromYDelta 起始点Y轴从标
android:toXDelta 结束点X轴坐标
android:toYDelta 结束点Y轴坐标
XML实现

1.在res/anim新建xml文件 anim_tween_translate.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:fillAfter="true"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="100"
    android:toYDelta="100" />

2.播放动画
通过AnimationUtils.loadAnimation(this, xxx);从XML文件中获取动画。再利用startAnimation将动画传递给指定控件显示。

Animation anim_tween_translate = AnimationUtils.loadAnimation(this, R.anim.anim_tween_translate);
ivAnimTweenTranslate.startAnimation(anim_tween_translate);
code实现

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)使用是绝对数值。
只有最后一个构造函数可以指定百分数和相对父控件的百分数。

代码实现

TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE, 0f, Animation.ABSOLUTE, 100f, Animation.ABSOLUTE, 0f, Animation.ABSOLUTE, 100f);
translateAnimation.setDuration(3000);

ivAnimTweenTranslate.startAnimation(translateAnimation);

3.3 RotateAnimation 旋转动画

android:fromDegrees 开始旋转的角度位置
正值代表顺时针方向度数,负值代码逆时针方向度数
android:toDegrees 结束时旋转到的角度位置
android:pivotX  旋转中心X轴坐标,
可以是数值、百分数、百分数p 三种样式,比如 50、50%、50%p,具体意义已在scale标签中
android:pivotY  旋转中心Y轴坐标
XML实现

1.在res/anim新建xml文件 anim_tween_rotate.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="90" />

2.播放动画
通过AnimationUtils.loadAnimation(this, xxx);从XML文件中获取动画。再利用startAnimation将动画传递给指定控件显示。

Animation anim_tween_rotate = AnimationUtils.loadAnimation(this, R.anim.anim_tween_rotate);
ivAnimTweenRotate.startAnimation(anim_tween_rotate);
code实现

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)

pivotXType、pivotYType有三个取值:Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF和Animation.RELATIVE_TO_PARENT;

代码实现

RotateAnimation rotateAnimation = new RotateAnimation(0, -90, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(3000);
ivAnimTweenRotate.startAnimation(rotateAnimation);

3.4 ScaleAnimation 缩放动画 动态调控件尺寸

ScaleAnimation自有属性
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,
当为数值50时,表示在当前View的左上角,即原点处加上50px,做为起始缩放点;
如果是50%,表示在当前控件的左上角加上自己宽度的50%做为起始点;
如果是50%p,那么就是表示在当前的左上角加上父控件宽度的50%做为起始点x轴坐标。
android:pivotY 缩放起点Y轴坐标
XML实现

1.在res/anim新建xml文件 anim_tween_scale.xml

<?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="700" />

2.播放动画
通过AnimationUtils.loadAnimation(this, xxx);从XML文件中获取动画。再利用startAnimation将动画传递给指定控件显示。

Animation anim_tween_scale = AnimationUtils.loadAnimation(this, R.anim.anim_tween_scale);
iv_anim_tween_scale.startAnimation(anim_tween_scale);
code实现

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)

android:pivotX中有三种取值,数,百分数,百分数p;
pivotXType用于将float pivotX变成三种取值,它的取值有三个,Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT;

实现代码:

ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 0.1f, 1.0f, 0.1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(3000);

iv_anim_tween_scale.startAnimation(scaleAnimation);

3.5 AnimationSet 动作合集

Set标签没有自己的属性,只有从Animation继承而来的属性
当它们用于Set标签时,就会对Set标签下的所有子控件都产生作用。

XML实现

1.在res/anim新建xml文件 anim_tween_set.xml

<?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>

2.播放动画
通过AnimationUtils.loadAnimation(this, xxx);从XML文件中获取动画。再利用startAnimation将动画传递给指定控件显示。

Animation anim_tween_set = AnimationUtils.loadAnimation(this, R.anim.anim_tween_set);
ivAnimTweenSet.startAnimation(anim_tween_set);
code实现

AnimationSet构造方法

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

增加动画的函数为:

public void addAnimation (Animation a)

代码实现

AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.1f);
ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
RotateAnimation rotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

AnimationSet animationSet = new AnimationSet(false);
animationSet.addAnimation(alphaAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(rotateAnimation);
animationSet.setDuration(3000);
animationSet.setFillAfter(true);

ivAnimTweenSet.startAnimation(animationSet);

3.6 插值器Interpolator

什么是插值器Interpolator?
Android在补间动画的开始和结束关键帧之间插入渐变值,它依据的根本就是Interpolator。
Interpolator负责控制动画的变化速度,使动画能以匀速、加速、减速、抛物线等多种速度进行变化。

3.6.0 Interpolator使用

xml中

<?xml version="1.0" encoding="utf-8"?>  
<scale xmlns:android="http://schemas.android.com/apk/res/android"  
 android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
  .../>

code中

ScaleAnimation 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());  
...
3.6.1 系统自带Interpolator
Interpolator的系统值

意义如下:

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

先看看系统加速器LinearInterpolator的写法:

//以常量速率改变的加速器LinearInterpolator
public class LinearInterpolator implements Interpolator {  
  
    public LinearInterpolator() {  
    }  
  
    public LinearInterpolator(Context context, AttributeSet attrs) {  
    }  
  
    public float getInterpolation(float input) {  
        return input;  
    }  
}  

//接口Interpolator(LinearInterpolator实现了Interpolator接口)
public interface Interpolator extends TimeInterpolator {  
}  

//(Interpolator接口则直接继承自TimeInterpolator)
public interface TimeInterpolator {  
    float getInterpolation(float input);  
/*
  参数input:
  input参数是一个float类型,它取值范围是0到1,表示当前动画的时间进度(与我们的任何设置无关).
  取0时表示动画刚开始,取1时表示动画结束,取0.5时表示动画中间的位置,其它类推。
 
  返回值:
  表示当前实际想要显示的进度。取值可以超过1也可以小于0。
  超过1表示已经超过目标值,小于0表示小于开始位置。
 */
} 

从上面可以看到,LinearInterpolator在getInterpolation函数中,直接把input值返回,即以当前动画的进度做为动画的数值进度,这也就表示当前动画的数值进度与动画的时间进度一致,比如,如果当前动画进度为0,那动画的数值进度也是0,那如果动画进度为0.5,那动画的数值进度也是在0.5,当动画结束,动画的进度就变成1了,而动画的数值进度也是1了。

则自定义Interpolator

public class MyInterpolator implements Interpolator {
    @Override
    public float getInterpolation(float input) {
        return 1-input;
    }
}

使用

ValueAnimator valueAnimatorInt = ValueAnimator.ofInt(0, 800);
valueAnimatorInt.setInterpolator(new MyInterpolator());
...

3.7 自定义补间动画(待补)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352