Android 动画 - 帧动画 & 补间动画

系列文章传送门:

Android 动画 - 帧动画 & 补间动画
Android 动画 - 插值器
Android 动画 - 属性动画


在移动开发中,动画可以丰富页面的 UI 效果,一个动画包含以下几个元素

  • 控件: 想实现动画的 View 等
  • 时长:动画的时长
  • 起始值,结束值:动画从开始和结束的值(比如移动,就是坐标值)
  • 插值器:定义了动画变化的速率

动画包含三大类型:帧动画(Frame),补间动画(Tween),属性动画(Property)

帧动画 (Frame)

顺序播放一组预先定义好的图。

  • 首先在 res/drawable/目录下定义xml,根节点为animation-list,设置动画播放的帧资源
  • 使用 AnimationDrawable 加载定义好的资源
<?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/wifi1" android:duration="500"/>
    <item android:drawable="@drawable/wifi2" android:duration="500"/>
    <item android:drawable="@drawable/wifi3" android:duration="500"/>
    <item android:drawable="@drawable/wifi4" android:duration="500"/>
    <item android:drawable="@drawable/wifi5" android:duration="500"/>
</animation-list>
  • oneshot 是否只展示一遍,设置为false会不停的循环播放动画
  • 根标签下,通过<item>标签对动画中的每一个图片进行声明
    • drawable 要播放的图片
    • duration 展示该图片的时间长度

使用AnimationDrawable 播放动画

view.setBackground(R.drawable.frame_animation);
AnimationDrawable animation = (AnimationDrawable)view.getBackground();
animation.start();

补间动画(Tween )

补间动画也称作 View 动画,只要定义 View,设置它开始和结束的位置,中间的 View 会由系统自动补齐,不需要准备每一帧动画。
View 动画主要支持四种效果:平移、缩放、旋转、透明度。实现这几种动画的类,都是 Animation 的子类。
使用这种动画可以通过在 xml 中实现,也可以在 类文件中定义。

TranslateAnimation

平移动画,对应标签为 <translate>

  • android:fromXDelta 起始 x 坐标
  • android:toXDelta 结束 x 坐标
  • android:fromYDelta 起始 y 坐标
  • android:toYDelta 结束 y 坐标

数值的表示方式如下:
数字:如10,表示当前坐标位置
百分比:如10%,表示当前 View 的坐标 + View 控件长度 10%
百分数p:如10%p,表示当前View的坐标 + 父控件长度 50%

范例:

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

在 java / kotlin 中使用该文件

Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_translate);
view.startAnimation(animation);

其中 duration 是动画的时长,interpolator 是动画的插值器,来定义动画变化的速率,每一种动画都具有这两个属性,还有一些其他的公共属性可配置,可以慢慢尝试。

类实现,等同于上面的配置(后面的几种动画实现方式是一样的)

// view 在 1s 间从(0, 0) 移动到 (100, 100)
TranslateAnimation animation = new TranslateAnimation(0, 0, 100, 100);
animation .setDuration(1000);
animation .setInterpolator(new DecelerateInterpolator());
view.startAnimation(animation);
  • TranslateAnimation 还有一个重载的构造函数
/**
 * @param fromXType 动画开始前的X坐标类型。取值范围为 ABSOLUTE(绝对位置)、RELATIVE_TO_SELF(以自身宽或高为参考)、RELATIVE_TO_PARENT(以父控件宽或高为参考)
 * @param fromXValue 动画开始前的X坐标值。当对应的 Type 为ABSOLUTE时,表示绝对位置;否则表示相对位置,1.0表示100%
 * @param toXType 动画结束后的 X 坐标类型
 * @param toXValue 动画结束后的 X 坐标值
 * @param fromYType 动画开始前的 Y 坐标类型
 * @param fromYValue 动画开始前的 Y 坐标值
 * @param toYType 动画结束后的 Y 坐标类型
 * @param toYValue 动画结束后的 Y 坐标值
*/
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
            int fromYType, float fromYValue, int toYType, float toYValue)

ScaleAnimation

缩放动画,对应标签 <scale>

  • fromXScale、 fromYScale 起始缩放值
  • toXScale、toYScale 目标缩放值
  • pivotX、pivotY 缩放的中心位置
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="2.0"
    android:toYScale="2.0"/>
  • ScaleAnimation 有三个构造函数
public ScaleAnimation(float fromX, float toX, float fromY, float toY) 

public ScaleAnimation(float fromX, float toX, float fromY, float toY,  float pivotX, float pivotY)

/**
 * @param fromX X坐标初始值
 * @param toX X坐标目标值
 * @param fromY Y坐标初始值
 * @param toY Y坐标目标值
 * @param pivotXType 缩放中心点的X坐标类型。取值范围有三种
 *        Animation.ABSOLUTE(绝对坐标)
 *        Animation.RELATIVE_TO_SELF(相对于自身View)
 *        Animation.RELATIVE_TO_PARENT(相对于父控件的坐标)
 * @param pivotXValue 缩放中心点的X坐标值当对应的 Type 为ABSOLUTE时,表示绝对位置;否则表示相对位置,1.0表示100%
 * @param pivotYType 缩放中心点的Y坐标类型
 * @param pivotYValue 缩放中心点的Y坐标
*/
public ScaleAnimation(float fromX, float toX, float fromY, float toY,  
                      int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
// 以view中心为缩放点,放大两倍
ScaleAnimation animation = new ScaleAnimation(
        1.0f, 2.0f, 1.0f, 2.0f,
        Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f
);
animation.setDuration(1000);
view.startAnimation(animation);

RotateAnimation

旋转动画,对应标签 <rotate>

  • fromDegree 旋转的起始角度
  • toDegree 旋转的结束角度
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
      android:fromDegree="0"
      android:toDegree="90"
      android:pivotX = "50%"
      android:pivotY="50%"
      android:duration = "3000"
/>
/**
 * @param fromDegrees 旋转的起始角度
 * @param toDegrees 旋转的结束角度
 * 默认旋转中心点为 (0, 0)
 */
public RotateAnimation(float fromDegrees, float toDegrees) 
 
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
    
/**
 * @param fromDegrees 旋转的起始角度
 * @param toDegrees 旋转的结束角度
 * @param pivotXType 
 * @param pivotXValue
 * @param pivotYType
 * @param pivotYValue
 */
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
        int pivotYType, float pivotYValue) {

AlphaAnimation

透明度动画,对应标签<alpha>

/**
 * @param fromAlpha 动画开始透明度 0~1
 * @param toAlpha 动画结束透明度
 */
public AlphaAnimation(float fromAlpha, float toAlpha) 

AnimationSet

AnimationSet 也继承于 Animation,可以同时处理多组动画,比如在平移的时候旋转等。

构造参数有一个参数,表示所添加的动画是否都共用一个插值器

/**
 * @param shareInterpolator 
 */
public AnimationSet(boolean shareInterpolator) {

常用的方法如下

// 添加动画
animationSet.addAnimation(new TranslateAnimation(0, 0, 100, 100));
// 设置插值器 默认 @android:anim/accelerate_decelerate_interpolator--> android:interpolator="`@android:anim/linear_interpolator`"
animationSet.setInterpolator(new LinearInterpolator());
// 设置动画持续时长,默认 0 --> android:duration="3000"
animationSet.setDuration(3000);
//设置动画结束之后是否保持动画的目标状态,默认 false --> android:fillAfter="true"
animationSet.setFillAfter(true);
//设置动画结束之后是否保持动画开始时的状态,默认 ture --> android:fillBefore="false"
animationSet.setFillBefore(false);
// 设置重复模式,RESTART(1) 顺序播放,REVERSE(2) 重复时逆向播放 android:repeatMode
animationSet.setRepeatMode(AnimationSet.REPEAT);
//设置重复次数,默认 0 --> android:repeatCount=-1
animationSet.setRepeatCount(AnimationSet.INFINITE);
//设置动画延时时间,默认 0 --> android:startOffset="2000"
animationSet.setStartOffset(2000);
//取消动画
animationSet.cancel();
//重置动画
animationSet.reset();

为 View 设置动画

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