Android开发艺术探索 - 第7章 Android动画深入分析

46 篇文章 0 订阅
39 篇文章 0 订阅

Animation resources
Property Animation Overview

1.View动画
  1. Tween补间动画
    四种动画效果,平移TranslateAnimation、缩放ScaleAnimation、旋转RotateAnimation和透明度AlphaAnimation,xml中对应四种标签的定义方式(res/anim/xxx.xml):
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@[package:]anim/interpolator_resource"
        android:shareInterpolator=["true" | "false"] >
        <alpha
            android:fromAlpha="float"
            android:toAlpha="float" />
        <scale
            android:fromXScale="float"
            android:toXScale="float"
            android:fromYScale="float"
            android:toYScale="float"
            android:pivotX="float"
            android:pivotY="float" />
        <translate
            android:fromXDelta="float"
            android:toXDelta="float"
            android:fromYDelta="float"
            android:toYDelta="float" />
        <rotate
            android:fromDegrees="float"
            android:toDegrees="float"
            android:pivotX="float"
            android:pivotY="float" />
        <set>
            ...
        </set>
    </set>
    
    • <set> 代表AniamtionSet类
      android:interpolator 插值器
      android:shareInterpolator 是否与子元素共享插值器
    • <alpha>
      android:fromAlpha
      android:toAlpha
    • <scale>
      android:fromXScale
      android:toXScale
      android:fromYScale
      android:toYScale
      android:pivotX 缩放中心
      android:pivotY 缩放中心
    • <translate>
      支持三种数据格式:-100100以%结尾,代表关于自身的比例;-100100以%p结尾,代表关于其父组件的比例;float值,绝对参数。
      android:fromXDelta
      android:toXDelta
      android:fromYDelta
      android:toYDelta
    • <rotate>
      android:fromDegrees
      android:toDegrees
      android:pivotX 旋转中心,也支持三种数据格式:相对于父组件左边缘的%p,相对于自身左边缘的%,相对于自身左边缘的x
      android:pivotY
    • 其他常用属性:
      android:duration
      android:fillAfter 动画结束后是否停留在结束位置
    • 应用动画
    ImageView image = (ImageView) findViewById(R.id.image);
    Animation hyperspaceJump = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
    image.startAnimation(hyperspaceJump);
    
    • 自定义插值器
      通过xml创建自己的插值器,然后引用现有的插值器,并修改其属性。如果不修改属性,则其表现相当于原始的插值器。
    <?xml version="1.0" encoding="utf-8"?>
    <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android"
        android:attribute_name="value"
        />
    
  • <accelerateInterpolator>
    android:factor 加速度,默认1。
  • <anticipateInterpolator>
    android:tension 张力,默认2。
  • <anticipateOvershootInterpolator>
    android:tension
    android:extraTension 乘以tension,默认1.5。
  • <cycleInterpolator>
    android:cycles 循环次数,默认1。
  • <decelerateInterpolator>
    android:factor 减速度,默认1。
  • <overshootInterpolator>
    android:tension 张力,默认2。
  1. Frame帧动画
    在xml中定义(res/drawable/xxx.xml),对应类AnimationDrawable。
    <?xml version="1.0" encoding="utf-8"?>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot=["true" | "false"] >
        <item
            android:drawable="@[package:]drawable/drawable_resource_name"
            android:duration="integer" />
    </animation-list>
    
    • android:oneshot
      是否播放一次。
    • 使用
      <?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/rocket_thrust1" android:duration="200" />
          <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
          <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
      </animation-list>
      
      ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
      rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
      
      rocketAnimation = rocketImage.getBackground();
      if (rocketAnimation instanceof Animatable) {
          ((Animatable)rocketAnimation).start();
      }
      
  2. View动画其他应用
    • LayoutAnimation
      作用于ViewGroup的子元素,常用于ListView。
      1. 定义LayoutAnimation
        <?xml version="1.0" encoding="utf-8"?>
        <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
            android:delay=""
            android:animationOrder=""
            android:animation=""/>
        
        android:delay 播放动画开始前的延时
        android:animationOrder 动画播放顺序,normal/reverse/random
        android:animation 指定动画
      2. 定义动画
      3. 在为ViewGroup设置android:layoutAnimation,指向定义的LayoutAnimation。
    • Activity切换动画
      overridePendingTransition(int enterAnim, int exitAnim)
      在startActivity和finish之后调用。
2.属性动画
  1. 使用
    • xml定义,存放位置res/animator/xxx.xml
    <set
      android:ordering=["together" | "sequentially"]>
    
        <objectAnimator
            android:propertyName="string"
            android:duration="int"
            android:valueFrom="float | int | color"
            android:valueTo="float | int | color"
            android:startOffset="int"
            android:repeatCount="int"
            android:repeatMode=["repeat" | "reverse"]
            android:valueType=["intType" | "floatType"]/>
    
        <animator
            android:duration="int"
            android:valueFrom="float | int | color"
            android:valueTo="float | int | color"
            android:startOffset="int"
            android:repeatCount="int"
            android:repeatMode=["repeat" | "reverse"]
            android:valueType=["intType" | "floatType"]/>
    
        <set>
            ...
        </set>
    </set>
    
  • <set>
    android:ordering 动画播放顺序:sequentially/together(default)
  • <objectAnimator>
    android:propertyName 属性名。如alpha/backgroundColor
    android:valueTo 需要指定。
    android:valueFrom 默认值通过getXX从target得到
    android:duration 默认300ms
    android:startOffset 调用start之后delay的时间
    android:repeatCount -1:无限循环;1:重复一次;0:不重复
    android:repeatMode 重复方式:reverse/repeat
    android:valueType intType/floatType,当animation color时不需要指定。
  • <animator>
    除了没有propertyName,与objectAnimator相同。
  • 使用
    AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
        R.animator.property_animator);
    set.setTarget(myObject);
    set.start();
    
    • 代码
    ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);
    animation.setDuration(1000);
    animation.start();
    
    animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator updatedAnimation) {
            // You can use the animated value in a property that uses the
            // same type as the animation. In this case, you can use the
            // float value in the translationX property.
            float animatedValue = (float)updatedAnimation.getAnimatedValue();
            textView.setTranslationX(animatedValue);
        }
    });
    
    ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);
    animation.setDuration(1000);
    animation.start();
    
  1. 插值器和估值器
    自定义插值器需要实现Interpolator或TimeInterpolator接口,自定义估值器需要实现TypeEvaluator接口。如果需要对除了int/float/Color之外的属性做动画,则一定需要实现自定义估值器。
  2. 动画监听
    • Animator.AnimatorListener:监听动画开始/停止/取消/重复
      onAnimationStart()
      onAnimationEnd()
      onAnimationRepeat()
      onAnimationCancel()
    • AnimatorListenerAdapter:AnimatorListener的空实现
    • ValueAnimator.AnimatorUpdateListener 如果使用的是ValueAnimator,则需要实现该接口
      onAnimationUpdate() 在动画的每一帧回调
  3. 属性动画原理
    ValueAnimator调用start方法之后,在整个动画的过程中,ValueAnimator会基于已经逝去的时间计算elapsed fraction;之后调用TimeInterpolator将elapsed fraction映射为interpolated fraction;最后,基于start value,end value和interpolated fraction通过TypeEvaluator计算出当前的property value。ref
    ValueAnimator只实现了计算动画属性值的工作,将属性值更新到target的过程需要自己完成;ObjectAnimator则在ValueAnimator基础上,完成了设置属性值的工作。所以前者有更大的灵活性,在使用后者时,一些注意事项:
    • 设置的属性必须有其set方法,foo->setFoo。如果没有set方法,有三种选择:如果有权限,直接添加一个set方法;使用一个wrapper类包装原始对象,然后设置set方法;使用ValueAnimator。
    • 如果参数中只指定了一个value,即没有指定start value,则该属性必须要有get方法,foo->getFoo
    • set方法和get方法操作的类型要一致。
  4. ViewPropertyAnimator
    因为Android 3.0之前的View动画的局限性,属性动画得以引入。而对于View来说,属性动画得益于引入了相应的属性:
    • translationX/translationY
    • rotation/rotationX/rotationY
    • scaleX/scaleY
    • pivotX/pivotY
    • x(left + translationX)/y(top + translationY)
    • alpha
      同时提供了更方便的API去实现View的属性动画:
    ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
    ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
    AnimatorSet animSetXY = new AnimatorSet();
    animSetXY.playTogether(animX, animY);
    animSetXY.start();
    
    PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
    PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
    ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();
    
    myView.animate().x(50f).y(100f);    // ViewPropertyAnimator
    
3.注意事项
  1. OOM问题->帧动画
  2. 内存泄漏->属性动画的无限循环,在Activity退出之后要停止
  3. 硬件加速
  4. View动画不能移动View本身,如果动画完成后,setVisibility(GONE)失效,需要调用view.clearAnimation()清除动画。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android开发艺术探索》是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。《Android开发艺术探索》从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层开发过程,融会贯通,介绍一些比较深入的知识点;第三,介绍一些核心技术和Android的性能优化思想。 《Android开发艺术探索》侧重于Android知识的体系化和系统工作机制的分析,通过《Android开发艺术探索》的学习可以极大地提高开发者的Android技术水平,从而更加高效地成为高级开发者。而对于高级开发者来说,仍然可以从《Android开发艺术探索》的知识体系中获益。 《Android开发艺术探索》是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。《Android开发艺术探索》从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层开发过程,融会贯通,介绍一些比较深入的知识点;第三,介绍一些核心技术和Android的性能优化思想。, 《 Android开发艺术探索》侧重于Android知识的体系化和系统工作机制的分析,通过《Android开发艺术探索》的学习可以极大地提高开发者的Android技术水平,从而更加高效地成为高级开发者。而对于高级开发者来说,仍然可以从《Android开发艺术探索》的知识体系中获益。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值