Android Animation解析

在app中增加一些动画效果能使我们的app更加绚丽,本文主要总结android中的Animation

Android中的Animation可以分为三种,View Animation,Drawable Animation ,Property Animation,其中第一种比较简单,只能实现一些简单的平移,缩放,旋转,透明度渐变的基本动画效果,第二种可以实现一种逐帧动画效果,而第三种属性动画比较复杂,Android 3.0之后出现,view动画能实现的它都能实现,除此之外还能实现很多其他的动画效果。

1.View动画,它的实现方式有两种,XML方式和javacode方式

XML方式:

  • 新建项目,在res目录中新建anim文件夹
  • 在anim目录中新建动画代码
  • 载入XML动画效果

直接上代码
透明度渐变动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <!--alpha渐变透明度动画
   fromAlpha 代表起始时透明度
   toAlpha 代表终止时透明度
   duration 动画持续事件 毫秒为单位-->
<alpha
    android:fromAlpha="0.0"
    android:toAlpha="1.0"
    android:duration="1000"/>
</set>

旋转动画

  <?xml version="1.0" encoding="utf-8"?>
  <set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--旋转动画
   interpolator 动画插值器,跟伸缩动画一样
   fromDegress 动画起始时物件的角度
   toDegress 动画结束时物件旋转的角度,当角度为负数表示逆时针旋转,当角度为正数表示顺时针旋转
                (负数from——to正数:顺时针旋转)
                (负数from——to负数:逆时针旋转)
                (正数from——to正数:顺时针旋转)
                (正数from——to负数:逆时针旋转)
   pivotX,pivotY表示旋转的x,y坐标,0%-100%取值。50%表示中点
   repeatMode代表重复类型:重复类型有两个值,reverse表示倒序回放,restart表示从头播放
   repeatCount代表重复次数,重复次数是int型
   -->
   <rotate
    android:duration="3000"
    android:fromDegrees="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="+350"
    android:repeatMode="restart"
    android:repeatCount="6"
    />
</set>

尺寸伸缩动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--渐变尺寸伸缩动画
   duration 渐变时间
   interpolator 指定一个动画的插入器
   有三种动画的插入器
   accelerate_decelerate_interpolator 加速-减速动画插入器
   accelerate_interpolator 加速动画插入器
   decelerate_interpolator 减速动画插入器
    fromXScale 动画起始时x坐标的伸缩尺寸
    toXScale 动画结束时x坐标的伸缩尺寸

    fromYScale 动画起始时Y坐标的伸缩尺寸
    toYScale 动画结束时Y坐标的伸缩尺寸
    0.0表示没有,1.0表示正常无收缩,值小于1.0表示收缩,值大于1.0表示放大
    pivotX 属性为动画相对于物件的X坐标的开始位置
    pivotY 属性为动画相对于物件的Y坐标的开始位置
    从0%-100%开始取值, 50%表示物件的X或者Y方向坐标上的中点位置
    fillAfter 当设置为true,该动画转化在动画结束后被应用-->
  <scale
    android:duration="1000"
    android:fillAfter="false"
    android:fromXScale="0.0"
    android:fromYScale="0.0"
    android:toXScale="1.4"
    android:toYScale="1.4"
    android:pivotX="50%"
    android:pivotY="50%"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>
</set>

位移动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
 <!--位置转移动画
   fromXDelta 动画开始时X坐标位置
   fromYDelta 动画开始时Y坐标位置
   toXDelta 动画结束时X坐标位置
   toYDelta 动画结束时Y坐标位置
   -->
<translate
    android:duration="2000"
    android:fromXDelta="30"
    android:fromYDelta="30"
    android:toXDelta="-80"
    android:toYDelta="300"
    />
</set>

载入XML动画效果

switch (v.getId()) {
        case R.id.bt_alpha:
            //载入动画
            mAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_scale:
            //载入动画
            mAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_translate:
            //载入动画
            mAnimation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_rotate:
            //载入动画
            mAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
            mIv.startAnimation(mAnimation);
            break;
        default:
            break;
    }

和点击事件一样,动画也具有监听,只需要我们的activity实现AnimationListener接口就行,我们可以在动画开始或者结束或者重复做一些别的操作

@Override
public void onAnimationStart(Animation animation) {//动画开始
}

@Override
public void onAnimationEnd(Animation animation) {//动画结束
}

@Override
public void onAnimationRepeat(Animation animation) {//动画重复
}

此外动画还有其他的属性,比如比较常用的android:repeatCount(XML中定义,表示重复次数),android:repeatMode(表示重复模式,重复类型有两个值,reverse表示倒序回放,restart表示从头播放),android:interpolator(设置差值器,这个在属性动画中会详细讲解)

上面讲了View动画的XML实现方式,下面介绍javacode实现方式,javacode的实现方式也很简单(不需要新建XML)

 switch (v.getId()) {
        case R.id.bt_alpha:
            mAnimation = new AlphaAnimation(0.1f, 0.1f);//新建一个透明度变化的动画
            mAnimation.setDuration(2000);//设置动画事件
            mIv.startAnimation(mAnimation);//开始动画
            break;
        case R.id.bt_scale:
            //渐变尺寸缩放动画效果
            mAnimation = new ScaleAnimation(0.0f, 2.0f, 1.5f, 1.5f, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.0f);
            mAnimation.setDuration(2000);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_translate:
            //移动动画效果
            mAnimation = new TranslateAnimation(0, 100, 0, 100);
            mAnimation.setDuration(2000);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_rotate:
            //旋转动画效果,这里是旋转360°
            mAnimation = new RotateAnimation(0.0f, 360.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            mAnimation.setDuration(2000);
            mIv.startAnimation(mAnimation);
            break;
        default:
            break;

看效果


View动画2.gif

2.Drawable Animation动画,它是把一帧一帧拼起来组成动画

  • 在res/drawable目录添加图片素材
Paste_Image.png
  • 在drawable文件夹中添加动画帧布局文件

      <?xml version="1.0" encoding="utf-8"?>
      <!--
          根标签为animation-list,其中oneshot代表着是否只展示一遍,设置为false会不停的循环播放动画  
          根标签下,通过item标签对动画中的每一个图片进行声明  
          android:duration 表示展示所用的该图片的时间长度  
      -->
      <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
          android:oneshot="false" >
          <item
      android:drawable="@drawable/cmmusic_progress_1"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_2"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_3"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_4"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_5"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_6"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_7"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_8"
      android:duration="150">
          </item>
      </animation-list>
    

引入XML布局文件实现动画

   //给ImageView设置drawable
    imgPic.setImageResource(R.drawable.loading_anim);
    //给动画资源赋值
    animationDrawable = (AnimationDrawable) imgPic.getDrawable();
  animationDrawable.start();//开始动画
   animationDrawable.stop(); //停止动画

实现效果类似于下拉加载的菊花转

3.属性动画

之所以引入属性动画有三点原因:

  • 属性动画不仅可以对view操作,也能对非view的对象进行操作
  • 属性动画不单单具有View动画的那些基本动画效果,也具有其他动画效果
  • View动画只是改变了View的显示效果而已,而不会真正去改变View的属性。而属性动画不单单是一种视觉上的动画,它是真正的改变了view的位置

属性动画实际上是一种不断地对值进行操作的机制,并将值赋值到指定对象的指定属性上,可以是任意对象的任意属性。所以我们仍然可以将一个View进行移动或者缩放,但同时也可以对自定义View中的Point对象进行动画操作了。我们只需要告诉系统动画的运行时长,需要执行哪种类型的动画,以及动画的初始值和结束值,剩下的工作就可以全部交给系统去完成了。

看完上面这段话还是不理解属性动画,那我们用起来就可以了
属性动画有三个类特别重要,分别是ValueAnimator,ObjectAnimator,AnimatorSet,前两个都是动画的执行类,用来执行属性动画的,而且ObjectAnimator是集成ValueAnimator的,而AnimatorSet顾名思义是动画的集合,用它来实现组合动画,我们来分别认识这三个类

VlaueAnimator

这个是属性动画最核心的类了,前面已经提到,属性动画实际上是一种不断对值进行操作的机制,并将值赋值到指定对象的指定属性上,而初始值和结束值的动画过渡就是这个类来负责计算的,我们只需要将初始值和结束值提供给ValueAnimator,并且告诉它动画所需运行的时长,那么ValueAnimator就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外,ValueAnimator还负责管理动画的播放次数、播放模式、以及对动画设置监听器等。

使用ValueAnimator

ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);  //值从0平滑到1,除此之外还可以用ofInt方法
anim.setDuration(300);  //动画持续时间
anim.start(); //动画开始

但是这段代码看不到任何界面效果,我们可以添加一个监听器方法,在动画执行过程中用不断进行回调

anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
@Override  
public void onAnimationUpdate(ValueAnimator animation) {  
    float currentValue = (float) animation.getAnimatedValue();  
    Log.d("TAG", "cuurent value is " + currentValue);  
}  
}); 

可以通过日志看到动画确实在执行

ObjectAnimator

ValueAnimator只是实现值的平滑过渡,使用场景并不是很多,而ObjectAnimator可以对任意对象的任意属性进行操作,一般我们是对view进行操作,因为ObjectAnimator是继承ValueAnimator,所以在ValueAnimator使用的方法在ObjectAnimator中也可以正常使用,直接上代码

        float curTrans = mIv.getTranslationX();//得到
        ObjectAnimator animator = ObjectAnimator.ofFloat(mIv, "translationX", curTrans,-500 ,curTrans);
        animator.setDuration(5000);
        animator.start();

上面的代码实现了平移的操作,其他例如透明度变化,旋转和伸缩都类似,不同的是ofFloat里面的参数发生变化

  • ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f); //透明度变化
  • ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f); //旋转
  • ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f); 缩放

第一个参数是view,第二个参数是动画类型,后面的参数根据动画类型的不同参数也不一样,关于第二个类型,虽然view里面没有alpha或者rotation这些属性,但是有get和set方法,其实ObjectAnimator内部的工作机制并不是直接对我们传入的属性名进行操作的,而是会去寻找这个属性名对应的get和set方法。

AnimatorSet

AnimatorSet是用来实现组合动画的,比如我们要进行一组组合动画,先进行位移操作,再进行旋转操作,再进行淡入淡出的操作,代码如下:

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

推荐阅读更多精彩内容

  • 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今...
    未聞椛洺阅读 2,651评论 0 10
  • 3.0以前,android支持两种动画模式,tween animation,frame animation,在an...
    Ten_Minutes阅读 1,643评论 0 4
  • 参考于:http://blog.csdn.net/guolin_blog/article/details/4353...
    墨染书阅读 2,905评论 0 2
  • 哪有什么武林秘籍 今天分享的书是《一学就会的超级记忆术》,一看到标题,就让我想起了上学时的武功秘籍。 我上四五年级...
    让dream照进现实阅读 281评论 0 0
  • 和老妈谈及她们那个年代的婚姻,老妈说,其实那时候的许多人,也是因为到了年纪,觉得结婚是该完成的一项任务,然后经人介...
    一蓑烟雨_6c60阅读 90评论 0 0