Android之属性动画Animator

Android 3.0之前已有动画框架Animation,但存在一些局限性,当某个元素发生视图动画后,其响应事件位置还在动画前的地方。于是3.0之后,Google提出了属性动画。

ObjectAnimator

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "translationX", 300); 

objectAnimator1.setInterpolator(new AccelerateInterpolator()); 

objectAnimator1.setDuration(2000); 

objectAnimator.setRepeatCount(ValueAnimator.INFINITE);//Animation.INFINITE 表示重复多次 

objectAnimator.setRepeatMode(ValueAnimator.RESTART);//RESTART表示从头开始,REVERSE表示从末尾倒播 

objectAnimator1.start();

第一个参数:操纵的view 第二个参数:操纵的动画属性值 第三个参数:可变数组参数

动画属性值

translationX和translationY:增量控制view从它布局容器左上角坐标偏移

ObjectAnimator.ofFloat(imageView, "translationX", 300f); 

rotation、rotationX、rotationY:控制view绕支点进行2D或3D旋转

ObjectAnimator.ofFloat(imageView, "rotation", 360); scaleX、scaleY:

控制view绕支点进行2D缩放

ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 0.5f,1f); 

alpha:控制view透明度,默认是1(不透明),0完全透明(不可见)

ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0.5f); 

x和y:描述view在容器最终位置

可变数组参数

可以有一个到N个,如果是一个值的话默认这个值是动画过渡值的结束值。如果有N个值,动画就在这N个值之间过渡。

动画监听

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "alpha", 0.5f, 1f); objectAnimator1.addListener(new Animator.AnimatorListener() {

@Override

public void onAnimationStart(Animator animation) {

}

@Override

public void onAnimationEnd(Animator animation) {

}

@Override

public void onAnimationCancel(Animator animation) {

}

@Override

public void onAnimationRepeat(Animator animation) {

}});

一般我们只关心onAnimationEnd,所以Android提供了AnimatorListenerAdapter:

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "alpha", 0.5f, 1f); objectAnimator1.addListener(new AnimatorListenerAdapter() 

@Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); 

} }); 

ValueAnimator

ValueAnimator 本身不提供任何动画效果,像个数值 发生器,用来产生具有一点规律数字。

ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100); valueAnimator.setTarget(imageView);  

valueAnimator.setDuration(2000).start(); 

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation)

 { 

Int value = (Integer) animation.getAnimatedValue(); //TODO use the value Toast.makeText(getApplicationContext(), "value=" + value, Toast.LENGTH_LONG).show(); } }); 

PropertyValuesHolder针对同一个对象多个属性,同时作用多种动画

PropertyValuesHolder propertyValuesHolder1 = PropertyValuesHolder.ofFloat("translationX", 300f); 

PropertyValuesHolder propertyValuesHolder2 = PropertyValuesHolder.ofFloat("alpha", 1f, 0.5f); 

PropertyValuesHolder propertyValuesHolder3 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f); 

PropertyValuesHolder propertyValuesHolder4 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f); 

ObjectAnimator.ofPropertyValuesHolder(imageView, propertyValuesHolder1, propertyValuesHolder2, propertyValuesHolder3, propertyValuesHolder4) .setDuration(5000).start(); 

AnimatorSet与PropertyValuesHolder类似,但AnimatorSet多了playTogether(同时执行)、playSequentially(顺序执行)、play(objectAnimator1).with(objectAnimator2)、before、after这些方法协同工作。

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0.5f); ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(imageView, "translationY", 300); ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 0, 1f); AnimatorSet animatorSet = new AnimatorSet(); 

animatorSet.setDuration(5000); 

animatorSet.playTogether(objectAnimator1, objectAnimator2,objectAnimator3); animatorSet.start(); 

xml使用属性动画

res下建立animator文件夹,然后建立res/animator/set_animator.xml

<?xml version="1.0" encoding="utf-8"?>

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"

android:duration="2000"

android:propertyName="alpha"

android:valueFrom="0.1"

android:valueTo="1.0"

android:valueType="floatType" />


调用:

Animator animator = AnimatorInflater.loadAnimator(getApplicationContext(), R.animator.set_animator); 

animator.setTarget(imageView); 

animator.start(); 

动画组合 set标签,有一个orderring属性设置为together,还有另一个值:sequentially(表示一个接一个执行)。

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"

android:ordering="together">

<objectAnimator

android:duration="1000"

android:propertyName="scaleX"

android:valueFrom="1"

android:valueTo="0.5" />

<objectAnimator

android:duration="1000"

android:propertyName="scaleY"

android:valueFrom="1"

android:valueTo="0.5" />

View的animate方法

Android 3.0后,谷歌给View增加animate方法直接驱动属性动画。

imageView.animate() .alpha(0.5f) .y(300) .setDuration(2000) 

//api min is 16

 .withStartAction(new Runnable() { @Override public void run() { } }) 

//api min is 16

.withEndAction(new Runnable() { @Override public void run() { } }).start();

 布局动画

设置子View过渡动画

LinearLayout parentLayout = (LinearLayout) findViewById(R.id.parentLayout); ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1); scaleAnimation.setDuration(2000); LayoutAnimationController layoutAnimationController=new LayoutAnimationController(scaleAnimation,0.5f); layoutAnimationController.setOrder(LayoutAnimationController.ORDER_NORMAL); parentLayout.setLayoutAnimation(layoutAnimationController);

通过Animator系列的API来控制动画的开始、停止和取消。

在之前的教程中,我们已经使用过多次Animator.start这个方法。这个方法是用来让动画从第一帧开始播放。该方法只是动画流控制方法集中的一个方法而已,完整的方法集合如下所示:

Animator.start() // start the animation from the beginning

Animator.end() // end the animation

Animator.cancel() // cancel the animation

Animator.pause() // added in API 19; pause the animation

Animator.resume() // added in API 19; resume a paused animation

start这个方法顾名思义是用来让动画从开头开始播放的。如果动画设置了一个大于0的播放延迟(startDelay),那么调用该方法后还需要等到延迟的时间过去才回开始播放。 我们有两种停止动画的方法,你可以用end方法抑或cancel方法来停止一个播放着的动画。在两种方式中动画都会终止并且只有再次调用start方法才会重新开始播放。两者的区别则在于停止后动画所在的状态,当你使用cancel方法来停止动画后,动画只是停止了它的时间轴,动画的状态会停在一个中间态(intermediate state)。如果通过end 方法来停止一个动画,那么动画会直接快进到该动画最后一帧并且停止,所有的对象都会保持在动画最终结束后的状态。 在 Kitkat 中增加的没有怎么被大家关注到的新API则是带来了动画可以暂停和恢复的能力。在那之前,一个动画如果被取消并且停留在当前的中间态,此时你用start方法去重启动画,动画只会从一开始重新播放。现在,你则可以调用pause方法来暂停当前播放中的动画,pause也会有和cancel方法一样的功效让动画停留在中间态,但是当你使用resume 方法去恢复这个动画的时候,动画会从这个状态继续播放下去。 

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

推荐阅读更多精彩内容

  • Animation Animation类是所有动画(scale、alpha、translate、rotate)的基...
    四月一号阅读 1,896评论 0 10
  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 2,673评论 0 10
  • Android框架提供了两种类型的动画:View Animation(也称视图动画)和Property Anima...
    RxCode阅读 1,610评论 1 5
  • 新家乔迁之时,我一时心血来潮,笨手笨脚搬回来一把藤椅。它泛着一层油腻色,呆拙质朴,傻头傻脑立在那里,与家中时尚明快...
    我是沐馨阅读 301评论 0 3
  • 如此温柔,如此温暖,平静清淡,日子在涌动的节奏里走着,知它总会暗藏起伏,平静下面波涛汹涌。时间久了,平静的日...
    笑的眼角阅读 117评论 0 0