浅析Android动画(二)——Property Anim属性动画

属性动画从字面上看就是对于属性的变换,它与变换动画最大的区别就是属性动画注重与用户的交互
举个例子:在变换动画中,将一个imageView设置点击事件,将其从左往右移动100dp,点击现有位置的imageView,并不会有点击事件,点击原有的位置将触发点击事件;而属性变化中,imageView的真实位置跟随着动画的移动而移动
变换动画请走链接浅析Android动画(一)——Tween Anim

相似的,属性动画拥有和变换动画相同的一些动画,alpha,translate,rotate,scale……但却比变化动画又更加精细,归根结底它变换的是属性,所有View对象拥有的属性都可以被操作。

属性动画也可以在布局文件中声明和在代码中声明,但从我个人角度来看,更喜欢在代码使用的形式,在这里只贴代码,有兴趣的可以自己去研究一下xml中的使用。

基本使用:

ObjectAnimator.ofFloat(Object 0,String propertyName,float...values);
ObjectAnimator.ofInt(Object 0,String propertyName,int...values);
/** 
* 第一个参数,要操作的对象 
* 第二个参数,要操作的对象属性,对象拥有的get,set属性都可以操作,相同的属性有相同的起始点 
* 第三个参数,float... values,变化的值,可以是一个,可以是多个 ,如果只有一个值,表示声明终止状态,并且无法多次触发动画效果,多个值可以多次触发效果
*/
共有方法:
setDuration(long duration);//设置时间
setStartDelay();//设置动画延迟播放的时间
setRepeatMode(int type);//设置重复模式,reverse反序,restart正序
setRepeatCount(int value);//设置重复次数,特殊的:-1为一直重复
addListener(AnimatorListener listener);//为动画设置监听事件,监听动画的开始、结束、取消、重复、暂停、恢复
setInterpolator(Interpolator interpolator);//设置插值器
Translate

属性:"translationX","translationY","X","Y",区别在于前二者是相对对象自身的左上角,后二者是相对于屏幕的左上角

//从现有位置移动到相对于 屏幕 左上角的位置,不可以重复,因为终点位置相同,多次触发不会重复效果,横坐标与原始位置一致
ObjectAnimator.ofFloat(mImageView,"Y",100f).setDuration(1000).start();
//从相对于 屏幕 左上角的指定位置移动到相对于 屏幕 左上角的另一个位置,可以重复触发效果,因为有起点终点,横坐标与现有原始一致
ObjectAnimator.ofFloat(mImageView,"Y",0f,100f).setDuration(1000).start();
//从相对于 自身 左上角的指定位置移动到相对于 自身 左上角的另一个位置,可以重复触发效果,因为有起点终点,横坐标与原始位置一致
ObjectAnimator.ofFloat(mImageView,"translationY",0f,100f).setDuration(1000).start();
//从现有位置移动到相对于 自身 左上角的坐标,多次触发不会重复效果,横坐标与原始位置一致
ObjectAnimator.ofFloat(mImageView,"translationY",100f).setDuration(1000).start();

类似的还有X方向的变化

Rotate

属性:"rotation","rotationX","rotationY"
"rotation"与变换动画中的一致,可以声明起止点,终点大的顺时针,否则逆时针,只声明一个终点,则旋转到相对于最原始的旋转角度
"rotationX"和"rotationY"是3维的动画效果:"rotationX"表示绕与X轴同方向的中线旋转(上下翻转),"rotationY"表示绕与Y轴同方向的中线旋转(左右翻转)

//旋转到相对于原始角度的值,不可以重复 
ObjectAnimator.ofFloat(mImageView,"rotation",360f).setDuration(1000).start();
//可以重复 
ObjectAnimator.ofFloat(mImageView,"rotation",0f,180f).setDuration(1000).start();
//绕x轴方向的中线旋转
ObjectAnimator.ofFloat(mImageView,"rotationX",0f,180f).setDuration(1000).start(); 
//绕y轴方向的中线旋转
ObjectAnimator.ofFloat(mImageView,"rotationY",0f,360f).setDuration(1000).start();
Scale

属性:"scaleX","scaleY"

ObjectAnimator.ofFloat(mImageView,"scaleX",0f).setDuration(1000).start();//不可多次触发
ObjectAnimator.ofFloat(mImageView,"scaleX",1f,0f).setDuration(1000).start();

这个很好理解

Alpha

属性:"alpha"

ObjectAnimator.ofFloat(mImageView,"alpha",0f).setDuration(1000).start();//不可多次触发
ObjectAnimator.ofFloat(mImageView,"alpha",1f,0f).setDuration(1000).start();
这个也很好理解

组合动画:

  • 最简单的 :
    这两个方法就已经可以进行同时进行组合动画了
ObjectAnimator.ofFloat(mImageView,"scaleX",0f).setDuration(1000).start();
ObjectAnimator.ofFloat(mImageView,"scaleY",0f).setDuration(1000).start();
  • 更好的办法:
    系统提供了更好的办法:PropertyValuesHolder,字面上就可以看到它是属性值的保存容器
    我们将动画先从PropertyValuesHolder使用:
PropertyValuesHolder p1=PropertyValuesHolder.ofFloat("scaleX",1f,0f);
PropertyValuesHolder p2=PropertyValuesHolder.ofFloat("scaleY",1f,0f);`
随后再调用
ObjectAnimator.ofPropertyValuesHolder(Object o,PropertyValuesHolder...values)方法
这个方法第一个参数是操作对象,第二个参数就是PropertyValuesHolder数组了;
`objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mImageView, p1, p2);
objectAnimator.setDuration(1000);
objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
objectAnimator.setRepeatCount(-1);
objectAnimator.start();
  • 更更更好的办法:
    类似于变换动画的AnimationSet动画集合,属性动画有它专门的集合:AnimatorSet,并且可以更加丰富的操作动画

先创建3个Animator:

ObjectAnimator animator1 = ObjectAnimator.ofFloat(mImageView, "alpha", 1f, 0.2f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(mImageView, "rotationX", 0f, 360f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(mImageView, "rotationY", 0f, 360f);`
再创建AnimatorSetA:
`AnimatorSet set=new AnimatorSet();

接下来神奇的事情将会发生:

set.playTogether(animator1,animator2,animator3);//同时进行动画
set.playSequentially(animator2,animator1,animator3);//按顺序播放
set.play(animator1).with(animator2);//两个动画一起进行
set.play(animator3).after(1000);//延迟1秒
set.play(animator3).after(animator1);//3在前2个动画之后
set.play(animator3).before(animator1);//3在前2个动画之前

发现只要非常简单的代码就可以实现很丰富的动画操作

监听事件

animator和animatorSet都有此监听事件

set.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
    }
    @Override
    public void onAnimationEnd(Animator animation) {
        Toast.makeText(AnimActivity.this,"anim end",Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onAnimationCancel(Animator animation) {
    }
    @Override
    public void onAnimationRepeat(Animator animation) {
    }
});

这个AnimatorListener()是系统已经设置好的,但是有一点不好,四个方法都要实现,而且缺少了暂停和恢复的监听
幸好系统有另一个方法

set.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationCancel(Animator animation) {
        super.onAnimationCancel(animation);
    }
    @Override
    public void onAnimationEnd(Animator animation) {
        Toast.makeText(AnimActivity.this,"anim end",Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onAnimationPause(Animator animation) {
      Toast.makeText(AnimActivity.this,"anim pause",Toast.LENGTH_SHORT).show();
    }
    @Override
    public void onAnimationResume(Animator animation) {
        Log.d("jc","resume");
      Toast.makeText(AnimActivity.this,"anim resume",Toast.LENGTH_SHORT).show();
    }
});

在这个匿名内部类里面可以选择性的重写这六个方法。

ValueAnimator:

ObjectAnimator也是继承了ValueAnimator这个类
属性动画的运行机制是通过不断地对值进行操作来实现的,而初始值和结束值之间的动画过渡就是由ValueAnimator这个类来负责计算的。

ValueAnimator mAnimator;
mAnimator=ValueAnimator.ofFloat(1,2);
//设置监听
mAnimator.setDuration(1000);mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float translate= (float) animation.getAnimatedValue();
        Log.d("jc”,"translate"+translate);
    }
});
//无限循环
mAnimator.setRepeatCount(-1);
mAnimator.setRepeatMode(ValueAnimator.REVERSE);
mAnimator.start();
D/jc: translate1.0
D/jc: translate1.0007129
D/jc: translate1.0026846
D/jc: translate1.0061558
...
D/jc: translate1.9709702
D/jc: translate1.9792609
D/jc: translate1.986185
D/jc: translate1.9917226
D/jc: translate1.995858
D/jc: translate1.9984586
D/jc: translate1.9998422
D/jc: translate1.9998002
D/jc: translate1.998333
D/jc: translate1.9954448
D/jc: translate1.9914355
D/jc: translate1.9858159
D/jc: translate1.9788108
D/jc: translate1.9704404
...
D/jc: translate1.0328355
D/jc: translate1.0239887
D/jc: translate1.0169019
D/jc: translate1.0107095
D/jc: translate1.0059125
D/jc: translate1.0025245
D/jc: translate1.000555
D/jc: translate1.0000099

可以看到结果在不断变换

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

推荐阅读更多精彩内容