Android 动画

动画分类
 Animation 作用于 View 的动画
 Transition 转场动画,一般用于 Activity 跳转时的过度动画

本文主要讲讲 Animation 的分类及各种使用方式
Animation
 类别上可以分为 2 种
   View Animation —— 动画仅仅用于展示,无法真正改变位置
   Property Animation —— 动画可以真正改变位置
区别这2种动画最明显的就是点击事件,请看下图


View Animation.gif

Property Animation.gif

 使用方法上又分为以下这几种
   FrameAnimation -> View Animation
   TweenAnimation -> View Animation
   ViewPropertyAnimator -> Property Animation
   ObjectAnimator -> Property Animation
   ValueAnimator -> Property Animation

上面就是大体的分类,可以先看看,大概有个轮廓。

接下来的是使用方法及效果展示

1. FrameAnimation (帧动画,逐帧显示)

20190313_150045.2019-03-13 15_14_40.gif

xml 创建,资源文件放在 res/drawable 文件夹下

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <!-- oneshot 是否只执行一次 true 仅播放一次 false 循环播放 默认为 false -->
    <!-- 每个 item 代表一帧,按顺序展示  
          drawable 显示的图片 
          duration 显示的时间,以毫秒计算 -->
    <item
        android:drawable="@drawable/frame1"
        android:duration="1000" />
    <item
        android:drawable="@drawable/frame2"
        android:duration="1000" />
    <item
        android:drawable="@drawable/frame3"
        android:duration="1000" />
</animation-list>

通过资源文件,创建 AnimationDrawable 后使用

// 创建 AnimationDrawable
AnimationDrawable animationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.anim_frame);
// 将 animationDrawable 动画设置给 view
view.setBackgroundDrawable(animationDrawable);
// 启动动画
animationDrawable.start();

// 循环播放时,可以用此方法停止动画
animationDrawable.stop();

代码方式创建

// 创建 AnimationDrawable
AnimationDrawable animationDrawable = new AnimationDrawable();
// addFrame(Drawable,duration) 添加帧
animationDrawable.addFrame(getResources().getDrawable(R.drawable.frame1), 1000); 
animationDrawable.addFrame(getResources().getDrawable(R.drawable.frame2), 1000);  
animationDrawable.addFrame(getResources().getDrawable(R.drawable.frame3), 1000);
// 是否只执行一次 true 仅播放一次 false 循环播放 默认为 false
animationDrawable.setOneShot(true);
// 将 animationDrawable 动画设置给 view
view.setBackgroundDrawable(animationDrawable);
//启动动画
animationDrawable.start();

2.TweenAnimation (补间动画)
包含 alpha(透明)、scale(缩放)、translate(位移)、rotate(旋转) 四种动画类型

补间动画.gif

xml 创建,资源放在 res/anim 文件夹下

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:repeatMode="restart">
    <!-- duration 动画市场,毫秒计算
         repeatMode 重复播放时的执行顺序 restart 从头开始 reverse 倒序-->

    <!-- 位移动画 0~任意数
         fromXDelta x 坐标起始点
         toXDelta   x 坐标结束点
         fromYDelta y 坐标起始点
         toYDelta   y 坐标结束点 -->
    <translate
        android:fromXDelta="100"
        android:fromYDelta="300"
        android:toXDelta="200"
        android:toYDelta="200" />

    <!-- 旋转动画 值 -~360
         fromDegrees 起始角度
         toDegrees   结束角度
         pivotX      x 轴中心点
         pivotY      y 轴中心点 -->
    <rotate
        android:fromDegrees="60"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />

    <!-- 缩放动画 值 0.0~1.0
         fromXScale x 轴起始缩放
         toXScale   x 轴结束缩放
         fromYScale y 轴起始缩放
         toYScale   y 轴结束缩放
         pivotX     x 轴中心点
         pivotY      y 轴中心点 -->
    <scale
        android:fromXScale="0.5"
        android:fromYScale="0.5"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1" />

    <!-- 透明动画 值 0.0~1.0
         fromAlpha 起始透明度
         toAlpha   结束透明度 -->
    <alpha
        android:fromAlpha="0.6"
        android:toAlpha="1" />
</set>

通过 AnimationUtils.loadAnimation 加载资源文件,设置动画

// 通过 AnimationUtils.loadAnimation 加载资源
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_tween);
//设置动画执行时间
animation.setDuration(1000);
//设置重复次数 -1 一直重复 次数>0 则重复几次  默认 为0  不管用
animation.setRepeatCount(-1);
// 重复模式 RESTART 从头开始  REVERSE 倒序开始  不管用
// animation.setRepeatMode(Animation.RESTART);
// 设置执行完动画后是使用转换过后的样式 true 是 使用 false 否 恢复到之前的样式 默认 false
// animation.setFillAfter(true);
//执行动画
view.startAnimation(animation);

代码方式创建

AnimationSet animationSet = new AnimationSet(true);
//位移动画
Animation translateAnimation = new TranslateAnimation(100, 200, 100, 200);
//旋转动画
Animation rotateAnimation = new RotateAnimation(60, 360);
//缩放动画
Animation scaleAnimation = new ScaleAnimation(0.5f, 1, 0.5f, 1);
//透明动画
Animation alphaAnimation = new AlphaAnimation(0.5f, 1.0f);
//添加动画
animationSet.addAnimation(translateAnimation);
animationSet.addAnimation(rotateAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.addAnimation(alphaAnimation);
//设置动画执行时间
animationSet.setDuration(2000);
//执行动画
view.startAnimation(animationSet);

需要注意的一些东西
setRepeatCount(重复次数)、setRepeatMode(重复模式) 这两个方法对一组动画设置是无效的,google 是这么设计的,如果想要使用,只能对每个动画单独设置,例如

//位移动画
Animation translateAnimation = new TranslateAnimation(100, 200, 100, 200);
translateAnimation.(-1);
//旋转动画
Animation rotateAnimation = new RotateAnimation(60, 360);
rotateAnimation.(-1);
//缩放动画
Animation scaleAnimation = new ScaleAnimation(0.5f, 1, 0.5f, 1);
scaleAnimation.(-1);
//透明动画
Animation alphaAnimation = new AlphaAnimation(0.5f, 1.0f);
alphaAnimation.(-1);

setFillAfter(true) 动画结束后是否使用转换过后的样式 true 使用 false 否 恢复到之前的样式 默认值 false

3.ViewPropertyAnimator(属性动画-最简单的使用方式)

动画-ViewPropertyAnimator.gif

//得到 ViewPropertyAnimator,设置各种动画
ViewPropertyAnimator viewPropertyAnimator = view.animate();
 //透明度
viewPropertyAnimator.alpha(0.5f)
                //x 轴缩放
                .scaleX(0.5f)
                //y 轴缩放
                .scaleY(0.5f)
                //x 轴移动距离
                .translationX(100)
                //y 轴移动距离
                .translationY(300)
                //x 轴旋转角度
                .rotationX(180)
                //y 轴旋转角度
                .rotationY(180)
                //动画时间
                .setDuration(2000)
                .start();

方法使用上有点区别
xxx() 代表目标值,如 alpha(0.1f) 将透明度设置为 0.1
xxxBy() 代表在原有的基础上改变,如 alphaBy(0.1f) ,将透明度加 0.1

属性动画需要满足以下条件才可使用

  • 被操作的属性要存在
  • 属性需要创建对应的 set()、get() 方法

4.ObjectAnimator(属性动画-简单的使用方式)
效果的话跟 ViewPropertyAnimator 一样

动画-ViewPropertyAnimator.gif

ObjectAnimator 的使用
使用 ObjectAnimator.ofxxx(Object target, String propertyName, float... values) 创建 ObjectAnimator 对象
target 作用的对象,即要使用动画的 view
propertyName 属性名称
values 动画变化的值,可输入多个值,1个长度代表动画结束的值;2个长度的话第一个为初始值,第二个为结束值;大于2个长度,则第一个到最后一个之间的值为过渡值。

在这可能会有个疑问,1个长度的时候初始值从哪来?初始值会从属性的 get() 方法获取

xxx 代表属性的类型,如 alpha 是 Float,则使用 ofFloat,一般情况下使用 ofInt()、ofFloat() 足矣,如果是自定义的类型,使用 ofObject()

使用 AnimatorSet 执行一组动画

 //动画集合
AnimatorSet animatorSet = new AnimatorSet();
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(view, "alpha", 1.0f, 0.5f);
ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(view, "scaleX", 0.5f);
ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(view, "scaleY", 0.5f);
ObjectAnimator translationXAnimator = ObjectAnimator.ofFloat(view, "translationX", 100);
ObjectAnimator translationYAnimator = ObjectAnimator.ofFloat(view, "translationY", 300);
ObjectAnimator rotationXAnimator = ObjectAnimator.ofFloat(view, "rotationX", 180);
ObjectAnimator rotationYAnimator = ObjectAnimator.ofFloat(view, "rotationY", 180);
//组合动画顺序 play 当前需要执行的动画
animatorSet.play(scaleXAnimator)
                //with 同时执行的动画
                .with(scaleYAnimator)
                .with(translationXAnimator)
                .with(translationYAnimator)
                //before 当前动画结束后需要执行的动画
                .before(alphaAnimator)
                //after 当前动画执行前需要执行的动画
                .after(rotationXAnimator)
                .after(rotationYAnimator);
 //设置动画同时执行
// animatorSet.playTogether(alphaAnimator, scaleXAnimator, scaleYAnimator, translationXAnimator,
// translationYAnimator, rotationXAnimator, rotationYAnimator);
//设置动画按顺序执行
// animatorSet.playSequentially(alphaAnimator, scaleXAnimator, scaleYAnimator, translationXAnimator,
// translationYAnimator, rotationXAnimator, rotationYAnimator);
//设置动画延时
// animatorSet.setStartDelay(2000);
//设置动画时间
animatorSet.setDuration(2000);
//启动动画
animatorSet.start();

5. ValueAnimator (属性动画-复杂的使用方式)

ValueAnimator 使用上会有些麻烦,需要自己监听动画,设置对应的变化,这种的自由度高一些,自己想怎么整就怎么整

ValueAnimator 的使用
使用 ValueAnimator.ofxxx() 创建 ValueAnimator 对象,通过 addUpdateListener() 方法监听值的变化,设置对应的动作
例如

// 创建 ValueAnimator 值的区间为 0~1
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1.0f);
// 设置动画时间
valueAnimator.setDuration(3000);
// 动画监听
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 得到动画值
                float alphaValue = (Float) animation.getAnimatedValue();
                // 将值设置给需要的 view
                view.setAlpha(alphaValue);
            }
        });
// 启动动画
valueAnimator.start();

如何监听动画的开始、结束、变化?
有几种监听方式,AnimationListener、AnimatorPauseListener、addUpdateListener
监听事件中通过 animation.getAnimatedValue() 获取动画值
AnimationListener 监听动画的开始、结束、重复

new AnimationListener() {
      @Override
      public void onAnimationStart(Animation animation) {
       // 动画启动的时候
      }

      @Override
      public void onAnimationEnd(Animation animation) {
      //动画结束的时候
      }
        
      @Override
      public void onAnimationRepeat(Animation animation) {
      //动画重复的时候
      }
}

AnimatorPauseListener 监听动画暂停、恢复

new AnimatorPauseListener() {
     @Override
     public void onAnimationPause(Animator animation) {
            
     }

     @Override
     public void onAnimationResume(Animator animation) {

     }
}

AnimatorUpdateListener 监听动画值变化

new AnimatorUpdateListener() {
     @Override
     public void onAnimationUpdate(ValueAnimator animation) {
      // 动画值变化的时候
     }
}

FrameAnimation 没有监听的方式
TweenAnimation 使用 setAnimationListener()
ViewPropertyAnimation 使用 setListener() 、setUpdateListener()
ObjectAnimator 使用 addListener()、addPauseListener()、addUpdateListener()
ValueAnimator 使用 addListener()、addPauseListener()、addUpdateListener()

属性动画比较重要的两个辅助类

1.Interpolator(速度变化器)
如果你想控制动画速度就用它,下面是几个常用的变化器
 LinearInterpolator—— 线性插值器、恒定变化
 AccelerateDecelerateInterpolator—— 先加速再减速
 AccelerateInterpolator—— 先慢后快
 DecelerateInterpolator—— 先快后慢
 AnticipateInterpolator—— 先回滚然后一直加速
 BounceInterpolator—— 到达结束点后会产生弹跳的效果

2.TypeEvaluator(类型估值器)
什么样的类型用什么样的类型估值器,这的类型就是动画参数的类型,下面是几个常用的估值器,如果是自定义的类型,那么就需要自己定义了
 IntEvaluator int 类型
 FloatEvaluator float 类型
 ArgbEvaluator argb 类型,一般用于颜色变化时使用

下面是 Interpolator 和 TypeEvaluator 使用时的参考链接,有想了解的可以戳戳看~
Interpolator 的具体效果及详细使用可以看看下面的链接
HenCoder Android 自定义 View 1-6:属性动画 Property Animation(上手篇)
TypeEvaluator 的具体效果及详细使用可以看看下面的链接
HenCoder Android 自定义 View 1-7:属性动画 Property Animation(进阶篇)

如果有哪方面不合适或者不明白的可以在评论区聊聊,我会及时改正或者优化~
类型-属性动画.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 【Android 动画】 动画分类补间动画(Tween动画)帧动画(Frame 动画)属性动画(Property ...
    Rtia阅读 6,386评论 1 38
  • 动画基础概念 动画分类 Android 中动画分为两种,一种是 Tween 动画、还有一种是 Frame 动画。 ...
    Rtia阅读 1,359评论 0 6
  • Animation Animation类是所有动画(scale、alpha、translate、rotate)的基...
    四月一号阅读 2,030评论 0 10
  • 名词: HTTP 每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的开销. 为了解决 TCP 连接的问...
    vckah阅读 236评论 0 0
  • 张晓风曾经写过一篇文章,《敬畏生命》。初读,感念于他对生命的感慨。而我,最近也多次遇见了生命,感念,感动于生命。 ...
    有凤来仪_c919阅读 343评论 0 2

友情链接更多精彩内容