集合动画AnimationSet

补间动画有四大类:透明度动画AlphaAnimation、旋转动画RotateAnimation、缩放动画ScaleAnimation、平移动画TranslateAnimation,而集合动画AnimationSet便是用来将几个补间动画组装起来。即在同一时刻,让某视图呈现出多种动画效果,如一边缩放一边旋转。

下面是AnimationSet的常用方法:
addAnimation : 添加动画。
setFillAfter : 设置是否维持结束画面。true表示动画结束后停留在结束画面,false表示动画结束后恢复到开始画面。
setRepeatMode : 设置重播模式。RESTART表示从头开始,REVERSE表示倒过来开始。
setDuration : 设置动画的持续时间。
setStartTime : 设置动画的开始时间。Animation.START_ON_FIRST_FRAME表示当前时间,其他值表示转换为整型数的时间。一般无需调用该方法,默认就是立即开始播放。
setInterpolator : 设置动画的插值器。

属性动画ObjectAnimator

视图View有许多属性,四种补间动画其实只用到了六个属性,分别是alpha、rotation、scaleX、scaleY、translationX、translationY,这六个属性对应View类的方法是setAlpha、setRotation、setScaleX、setScaleY、setTranslationX、setTranslationY。属性动画便是为了突破补间动画的局限,它让View所有的公开属性都能够实现动画效果,例如背景颜色、文字颜色等等,只要设定某属性的起始值与终止值,即可实现该属性的动画渐变。

下面是ObjectAnimator的常用方法:
ofInt : 定义整型属性的属性动画。
ofFloat : 定义浮点型属性的属性动画。
ofObject : 定义对象属性的属性动画。用于属性值不是整型与浮点型的,例如Rect对象。
setDuration : 设置动画的持续时间。
setInterpolator : 设置动画的插值器。
start : 开始播放动画。

属性动画组合AnimatorSet

AnimationSet用来组装补间动画,而用于组装属性动画的另有其人,它就是AnimatorSet。AnimatorSet组装属性动画是通过内部类Builder实现的,下面是AnimationSet.Builder的组装方法:
with : 与当前动画一起播放。
before : 在当前动画之前播放。
after : 在当前动画之后播放。

下面是AnimatorSet的常用方法:
setDuration : 设置动画的持续时间。
setInterpolator : 设置动画的插值器。
play : 设置初始动画,即当前动画。该方法返回AnimationSet.Builder对象,可对Builder对象添加新的属性动画,从而实现组装功能。
start : 开始播放动画。
pause : 暂停播放。
resume : 恢复播放。
cancel : 取消播放。
end : 结束播放。end方法与cancel方法的区别在于:cancel方法会触发AnimatorListener的onAnimationCancel事件,而end方法不会触发该事件。
isRunning : 判断动画是否在播放。

插值器和估值器

插值器

插值器用来控制属性变化的速率,也可以理解为动画播放的速度,默认是匀速播放。要设置一个插值器,调用setInterpolator方法即可,不管是补间动画、还是集合动画、还是属性动画、还是属性动画组合,都可以设置插值器。

下面是插值器具体实现类的说明:
LinearInterpolator : 匀速
AccelerateInterpolator : 加速
DecelerateInterpolator : 减速
AccelerateDecelerateInterpolator : 钟摆速度,即前半段加速、后半段减速
AnticipateInterpolator : 后退几步再往前冲
AnticipateOvershootInterpolator : 后退几步再往前冲,冲过头再归位
BounceInterpolator : 皮球落地(落地后会弹起几次)
CycleInterpolator : 以开始位置为中线而晃动(类似摇摆,开始位置与结束位置的距离就是摇摆的幅度)
OvershootInterpolator : 冲过头再归位

估值器

估值器专用于属性动画,主要是描述该属性的数值变化要采用什么单位,比如说整型数的渐变数值都要取整,颜色的渐变数值要按照RGB格式取整,矩形的渐变数值要同时对横坐标和纵坐标取整等等。要设置属性动画的估值器,调用ObjectAnimator的setEvaluator方法即可。

下面是估值器具体实现类的说明(如果属性类型是自定义的,那也得自定义对应的估值器):
IntEvaluator : 整型估值器
FloatEvaluator : 浮点型估值器
ArgbEvaluator : 颜色估值器
RectEvaluator : 矩形估值器

属性方法与估值器的对应关系

为方便记忆属性动画中属性方法与估值器的关系,下面列出相关对象的对应关系:
ofInt——IntEvaluator——颜色
ofInt——ArgbEvaluator——颜色,如backgroundColor、textColor等等
ofFloat——FloatEvaluator——大部分属性,如alpha、rotation、scaleY、translationX等等
ofObject——RectEvaluator——范围,如clipBounds

代码例子

下面是集合动画的代码示例

import com.example.exmanimation.util.MetricsUtil;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;public class SetActivity extends Activity implements OnClickListener, AnimationListener {private final static String TAG = "SetActivity";private ImageView iv_set;private Animation translateAnimation, alphaAnimation, scaleAnimation, rotateAnimation;private AnimationSet setAnimation;private Animation translateAnimation9;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_set);Button btn_set_start = (Button) findViewById(R.id.btn_set_start);Button btn_translate_start = (Button) findViewById(R.id.btn_translate_start);btn_set_start.setOnClickListener(this);btn_translate_start.setOnClickListener(this);iv_set = (ImageView) findViewById(R.id.iv_set);translateAnimation = new TranslateAnimation(0.1f, 0.1f, 0.1f,MetricsUtil.dip2px(this, 250));translateAnimation.setDuration(3000);translateAnimation.setFillAfter(true);translateAnimation.setInterpolator(new AccelerateInterpolator());alphaAnimation = new AlphaAnimation(1.0f, 0.1f);alphaAnimation.setDuration(3000);alphaAnimation.setFillAfter(true);scaleAnimation = new ScaleAnimation(1.0f, 0.1f, 1.0f, 1.0f);scaleAnimation.setDuration(3000);scaleAnimation.setFillAfter(true);rotateAnimation = new RotateAnimation(0f, 360f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);rotateAnimation.setDuration(3000);rotateAnimation.setFillAfter(true);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_translate_start) {translateAnimation9 = new TranslateAnimation(0.1f, 0.1f, 0.1f,MetricsUtil.dip2px(this, 250));translateAnimation9.setDuration(3000);translateAnimation9.setFillAfter(true);translateAnimation9.setInterpolator(new AccelerateInterpolator());iv_set.startAnimation(translateAnimation9);translateAnimation9.setAnimationListener(this);} else if (v.getId() == R.id.btn_set_start) {setAnimation = new AnimationSet(true);setAnimation.addAnimation(translateAnimation);setAnimation.addAnimation(alphaAnimation);setAnimation.addAnimation(scaleAnimation);setAnimation.addAnimation(rotateAnimation);setAnimation.setFillAfter(true);iv_set.startAnimation(setAnimation);setAnimation.setAnimationListener(this);}}@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {Animation translateAnimation2 = new TranslateAnimation(0.1f, 0.1f, MetricsUtil.dip2px(this, 250), 0.1f);translateAnimation2.setDuration(3000);translateAnimation2.setFillAfter(true);Animation alphaAnimation2 = new AlphaAnimation(0.1f, 1.0f);alphaAnimation2.setDuration(3000);alphaAnimation2.setFillAfter(true);Animation scaleAnimation2 = new ScaleAnimation(0.1f, 1.0f, 1.0f, 1.0f);scaleAnimation2.setDuration(3000);scaleAnimation2.setFillAfter(true);Animation rotateAnimation2 = new RotateAnimation(0f, -360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);rotateAnimation2.setDuration(3000);rotateAnimation2.setFillAfter(true);if (animation.equals(translateAnimation9)) {Animation translateAnimation10 = new TranslateAnimation(0.1f, 0.1f, MetricsUtil.dip2px(this, 250), 0.1f);translateAnimation10.setDuration(3000);translateAnimation10.setFillAfter(true);translateAnimation10.setInterpolator(new DecelerateInterpolator());iv_set.startAnimation(translateAnimation10);} else if (animation.equals(setAnimation)) {AnimationSet setAnimation2 = new AnimationSet(true);setAnimation2.addAnimation(translateAnimation2);setAnimation2.addAnimation(alphaAnimation2);setAnimation2.addAnimation(scaleAnimation2);setAnimation2.addAnimation(rotateAnimation2);setAnimation2.setFillAfter(true);iv_set.startAnimation(setAnimation2);}}@Overridepublic void onAnimationRepeat(Animation animation) {}}

下面是属性动画及属性动画组合的代码示例

import com.example.exmanimation.util.MetricsUtil;import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;public class SetActivity extends Activity implements OnClickListener, AnimationListener {private final static String TAG = "SetActivity";private ImageView iv_set;private Animation translateAnimation, alphaAnimation, scaleAnimation, rotateAnimation;private AnimationSet setAnimation;private Animation translateAnimation9;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_set);Button btn_set_start = (Button) findViewById(R.id.btn_set_start);Button btn_translate_start = (Button) findViewById(R.id.btn_translate_start);btn_set_start.setOnClickListener(this);btn_translate_start.setOnClickListener(this);iv_set = (ImageView) findViewById(R.id.iv_set);translateAnimation = new TranslateAnimation(0.1f, 0.1f, 0.1f,MetricsUtil.dip2px(this, 250));translateAnimation.setDuration(3000);translateAnimation.setFillAfter(true);translateAnimation.setInterpolator(new AccelerateInterpolator());alphaAnimation = new AlphaAnimation(1.0f, 0.1f);alphaAnimation.setDuration(3000);alphaAnimation.setFillAfter(true);scaleAnimation = new ScaleAnimation(1.0f, 0.1f, 1.0f, 1.0f);scaleAnimation.setDuration(3000);scaleAnimation.setFillAfter(true);rotateAnimation = new RotateAnimation(0f, 360f,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);rotateAnimation.setDuration(3000);rotateAnimation.setFillAfter(true);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_translate_start) {translateAnimation9 = new TranslateAnimation(0.1f, 0.1f, 0.1f,MetricsUtil.dip2px(this, 250));translateAnimation9.setDuration(3000);translateAnimation9.setFillAfter(true);translateAnimation9.setInterpolator(new AccelerateInterpolator());iv_set.startAnimation(translateAnimation9);translateAnimation9.setAnimationListener(this);} else if (v.getId() == R.id.btn_set_start) {setAnimation = new AnimationSet(true);setAnimation.addAnimation(translateAnimation);setAnimation.addAnimation(alphaAnimation);setAnimation.addAnimation(scaleAnimation);setAnimation.addAnimation(rotateAnimation);setAnimation.setFillAfter(true);iv_set.startAnimation(setAnimation);setAnimation.setAnimationListener(this);}}@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {Animation translateAnimation2 = new TranslateAnimation(0.1f, 0.1f, MetricsUtil.dip2px(this, 250), 0.1f);translateAnimation2.setDuration(3000);translateAnimation2.setFillAfter(true);Animation alphaAnimation2 = new AlphaAnimation(0.1f, 1.0f);alphaAnimation2.setDuration(3000);alphaAnimation2.setFillAfter(true);Animation scaleAnimation2 = new ScaleAnimation(0.1f, 1.0f, 1.0f, 1.0f);scaleAnimation2.setDuration(3000);scaleAnimation2.setFillAfter(true);Animation rotateAnimation2 = new RotateAnimation(0f, -360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);rotateAnimation2.setDuration(3000);rotateAnimation2.setFillAfter(true);if (animation.equals(translateAnimation9)) {Animation translateAnimation10 = new TranslateAnimation(0.1f, 0.1f, MetricsUtil.dip2px(this, 250), 0.1f);translateAnimation10.setDuration(3000);translateAnimation10.setFillAfter(true);translateAnimation10.setInterpolator(new DecelerateInterpolator());iv_set.startAnimation(translateAnimation10);} else if (animation.equals(setAnimation)) {AnimationSet setAnimation2 = new AnimationSet(true);setAnimation2.addAnimation(translateAnimation2);setAnimation2.addAnimation(alphaAnimation2);setAnimation2.addAnimation(scaleAnimation2);setAnimation2.addAnimation(rotateAnimation2);setAnimation2.setFillAfter(true);iv_set.startAnimation(setAnimation2);}}@Overridepublic void onAnimationRepeat(Animation animation) {}}

点击下载本文用到的集合动画与属性动画的工程代码

点此查看Android开发笔记的完整目录

Android开发笔记(九十六)集合动画与属性动画相关推荐

  1. Android开发笔记(六十一)文件下载管理DownloadManager

    下载管理DownloadManager 文件下载其实是网络数据访问的一种特殊形式,使用普通的http请求也能完成,就是实现起来会繁琐一些.因为下载功能比较常用,而且业务功能相对统一,所以从Androi ...

  2. 属性数量限制android,Android开发笔记 今天学到的一些属性

    Android开发笔记 今天学到的一些属性 更新时间:2012年11月07日 10:23:33   作者: 离开实验室之前再贴上今天下午自己学到的一些基础知识 上午干嘛了呢,忙着数据恢复呢 1.最后程 ...

  3. Android开发笔记(六十五)多样的菜单

    菜单Menu Android的菜单分为两类:选项菜单和上下文菜单,默认使用选项菜单.菜单的布局文件存放在res/menu目录下,使用ADT新建一个Android工程,首页代码MainActivity中 ...

  4. Android开发笔记(六十二)HTTP数据格式的解析

    json解析 android有两种主流的json解析方案,一种是sdk自带的由Google提供的json(包名前缀为org.json),另一种是Alibaba提供的第三方jar包fastjson(包名 ...

  5. Android开发笔记(十五)淡入淡出动画TransitionDrawable

    说到淡入淡出动画,可能大家会想到补间动画里面的AlphaAnimation,不过这个深浅动画只能对透明度做渐变效果,也就是只能对一个图形做深浅的颜色变换.如果我们想要从A图片逐渐变为B图片,也就是要实 ...

  6. Android开发笔记(十四)圆弧进度动画CircleAnimation

    一个好看的APP,都有不少精致的动画效果.熟练运用各种动画技术,可让我们的APP灼灼生辉.Android在技术上把动画分为了三类,分别是帧动画FrameAnimation.补间动画TweenAnima ...

  7. Android开发笔记(六十九)JNI实战

    NDK NDK的用途 NDK全称为Native Development Kit,意即原生的开发工具,NDK允许开发者在APP中通过C/C++代码执行部分程序.它是Android提供的方便开发者通过JN ...

  8. Android开发笔记(六十八)工程库打包

    写好一个Android模块,比如说一个自定义控件或某个功能的sdk,然后开放出来给别人使用,就得通过某种方式把源码提供给对方.常见的打包方式有: 一.直接给源码,由开发者把代码加入到自己的工程中 该方 ...

  9. Android开发笔记(六十六)自定义对话框

    AlertDialog Android中最常用的对话框是AlertDialog,它可以完成常见的交互操作,如提示.确认.选择等等,然后就是进度对话框ProgressDialog(参见< Andr ...

  10. Android开发笔记(六十四)网页加载与JS调用

    内置浏览器 网页视图WebView 如果一个网站已经有现成的网页及业务逻辑,那么使用WebView将其内嵌到app中,省去了app重画页面与http通信的事情,无疑是更经济的做法.WebView就是A ...

最新文章

  1. 43 JavaScript中的浅拷贝与深拷贝
  2. zb如何导出自己画的_zbrush纹理贴图(zbrush怎么导出映射贴图)
  3. VMware与KVM全方面对比
  4. 问题解决:QtCreator屏蔽指定警告:如C4819等
  5. jzoj4313 电话线铺设(最小生成树+最近公共祖先)
  6. java中ant是干什么的_Java_Ant详解(转载)
  7. 【循序渐进学Python】4. Python中的序列——字典
  8. 下载官方Intel的Windows 10网卡驱动
  9. property属性
  10. plist序列帧合图导出单独的图片
  11. Win10开电脑热点以后手机连接会IP配置失败或者一直显示获取IP中
  12. 人物-胡玮炜:胡玮炜
  13. 力科(Lecroy)示波器专用波形文件(轨迹文件/trace文件/.trc文件)在MATLAB上的解析与回写
  14. 《高绩效成果教练》课程笔记及思考
  15. 淘宝和微信的扫码登录实现原理
  16. 计算机名(主机名)、本机地址(IP/IPv4)、localhost、127.0.0.1的关系
  17. 网页上的内容无法选中复制该如何解决?
  18. 再谈异常处理try-catch-finally
  19. php 1075 incorrect,windows无法启动wlan错误1075怎么办
  20. pandas中的axis=0,axis=1具体含义(转)

热门文章

  1. sklearn 3. 实例:随机森林在乳腺癌数据上的调参
  2. Keil5配置GCC编译器编译STM32工程
  3. 【十七】文件译文:user.properties (用户配置文件)
  4. linux控制协程参数,Linux高性能网络:协程系列05-协程实现之原语操作
  5. linux mysql集群 备份与恢复,Linux下MySQL的备份和恢复
  6. Docker配置国内加速镜像源
  7. getAttribute和getParameter的区别
  8. 张家口全国计算机等级考试,河北省张家口市2018年上半年计算机等级考试公告...
  9. mysql中datetime有带时区_如何在MySQL中存储datetime与时区信息
  10. E. 2-3-4 Tree