欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

深入浅析Android开发动画

程序员文章站 2022-03-11 15:43:50
目录一、View动画View动画包括:补间动画、逐帧动画。1.1 补间动画作用对象:View动画效果:平移、缩放、旋转、透明度名称子类效果平移动画TranslateAnimation移动View缩放动画ScaleAnimation放大/缩小View旋转动画RotateAnimation旋转View透明度动画AlphaAnimation改变View的透明度四种动画xml代码

目录

深入浅析Android开发动画

一、View动画

View动画包括:补间动画、逐帧动画。

深入浅析Android开发动画

1.1 补间动画

作用对象:View

动画效果:平移、缩放、旋转、透明度

名称 子类 效果
平移动画 TranslateAnimation 移动View
缩放动画 ScaleAnimation 放大/缩小View
旋转动画 RotateAnimation 旋转View
透明度动画 AlphaAnimation 改变View的透明度

四种动画xml代码

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
        android:shareInterpolator="true"
        android:interpolator = "@android:anim/linear_interpolator">
    <rotate     
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="float"
        android:pivotY="float" />

    <translate
        android:fromXDelta="float"
        android:fromYDelta="float"
        android:toXDelta="float"
        android:toYDelta="float" />
    <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"/>
</set> 

以下是对上面代码的说明。

1.set:表示动画集合,对应AnimationSet
  • interpolator:表示动画集合所采用的插值器,影响动画的速度。可以不指定,默认是accelerate_decelerate_interpolate(加速减速插值器)。下文属性动画会详细介绍插值器的相关知识。
  • shareInterpolator:表示集合中的动画是否和集合共享一个插值器。如果集合不指定插值器, 那么子动画就需要单独制定所需的插值器或者使用默认值。
  • fillAfter:表示动画结束时是否保持动画结束时的状态
2.rotate:表示旋转动画,对应RotateAnimation类。
  • fromDegrees:动画起始时物件的角度 (0度指X轴正方向所在方向)
  • toDegrees:动画结束时物件旋转的角度

以上两个属性共同确定旋转方向,原则是:当角度(to-from)为数时表示逆时针旋转,反之。

  • pivotY:动画旋转的轴点的X坐标
  • pivotX:动画旋转的轴点的Y坐标
3.translate:表示平移动画,对应TranslateAnimation
  • android:fromXDelta:动画起始时X坐标上的位置。
  • android:toXDelta:动画结束时X坐标上的位置。
  • android:fromYDelta:动画起始时Y坐标上的位置。
  • android:toYDelta:动画结束时Y坐标上的位置。

注意:以上四个属性以及后面几个类似属性的取值可能是数值、百分数、百分数p,各自含义是:

  • 50:以View左上角为原点沿坐标轴正方向偏移50px。
  • 50%:以View左上角为原点沿坐标轴正方向偏移View宽/高度的50%。
  • 50%p:以View左上角为原点沿坐标轴正方向偏移父(parent)控件宽/高度的50%。区别如图:

深入浅析Android开发动画

4.alpha:表示透明度动画,对应AlphaAnimation
  • fromAlpha:动画起始时透明度
  • toAlpha:动画结束时透明度

以上两个属性值:从0-1中取值。注意:

  • 值=0.0 :表示完全透明
  • 值=1.0 :表示完全不透明
5.scale:表示缩放动画,对应ScaleAnimation
  • fromXScale:动画起始时X坐标上的伸缩尺寸
  • toXScale:动画结束时X坐标上的伸缩尺寸
  • fromYScale:动画起始时Y坐标上的伸缩尺寸
  • toYScale:属性为动画结束时Y坐标上的伸缩尺寸

以上四个属性值的值含义:

  • 值=0.0 :表示收缩到没有
  • 值<1.0 :表示收缩
  • 值=1.0 :表示无伸缩
  • 值>1.0 :表示放大
  • pivotX:动画相对于物件的X坐标的开始位置
  • pivotY:动画相对于物件的Y坐标的开始位置

以上两个属性值表示缩放的轴点:从0%-100%中取值。

1.1.1 单个动画使用

在XML/Java代码中设置,在XML中设置,动画描述的可读性更好。在Java代码中设置,动画效果可动态创建。

以平移动画为例;

XML设置法
  • 步骤1:xml设置

深入浅析Android开发动画

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000" //动画持续时间
    android:startOffset ="1000"// 动画延迟开始时间(ms)
    android:fillBefore = "true"// 动画播放完后,视图是否会停留在动画开始的状态,默认为true
    android:fillAfter = "false"// 动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
    android:fillEnabled= "true"// 是否应用fillBefore值,对fillAfter值无影响,默认为true
    android:repeatMode="restart"// 选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart
    android:repeatCount = "0"重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复

    android:fromXDelta="0"// 视图在水平方向x 移动的起始值
    android:toXDelta="500"// 视图在水平方向x 移动的结束值

    android:fromYDelta="0"// 视图在竖直方向y 移动的起始值
    android:toYDelta="0" // 视图在竖直方向y 移动的结束值
    /> 
  • 步骤2:java代码
public class MainActivity extends AppCompatActivity {
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.button);
        final Animation animation = AnimationUtils.loadAnimation(this,R.anim.animation); //创建动画对象,传入xml文件
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                button.startAnimation(animation); //启动动画
            }
        });
    }
} 
  • 效果图

深入浅析Android开发动画

Java代码设置法
 Button mButton = (Button) findViewById(R.id.Button);
        // 步骤1:创建 需要设置动画的 视图View

        Animation translateAnimation = new TranslateAnimation(0,500,0,0);
        // 步骤2:创建平移动画的对象:平移动画对应的Animation子类为TranslateAnimation
        // 参数分别是:
        // 1. fromXDelta :视图在水平方向x 移动的起始值
        // 2. toXDelta :视图在水平方向x 移动的结束值
        // 3. fromYDelta :视图在竖直方向y 移动的起始值
        // 4. toYDelta:视图在竖直方向y 移动的结束值

        translateAnimation.setDuration(3000);
        // 固定属性的设置都是在其属性前加“set”,如setDuration()
        mButton.startAnimation(translateAnimation);
        // 步骤3:播放动画 

效果图跟上图一样。

1.1.2 组合动画使用

  • 步骤1:XML设置
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"

android:duration="3000"
android:startOffset ="0"
android:fillBefore = "true"
android:fillAfter = "false"
android:fillEnabled= "true"
android:repeatMode="restart"
android:repeatCount = "0"
android:interpolator = "@android:anim/linear_interpolator">

<rotate  //旋转动画
    android:duration="1000"
    android:fromDegrees="0"// 动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
    android:toDegrees="360"// 动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
    android:pivotX="50%"// 旋转轴点的x坐标
    android:pivotY="50%"// 旋转轴点的y坐标
    android:repeatMode="restart"
    android:repeatCount="infinite"
    />

<translate //平移动画
    android:duration="10000"
    android:startOffset ="1000"
    android:fromXDelta="-50%p"
    android:fromYDelta="0"
    android:toXDelta="50%p"
    android:toYDelta="0" />
</set> 
  • 步骤2:Java代码设置
public class MainActivity extends AppCompatActivity {
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.button);
        final Animation animation = AnimationUtils.loadAnimation(this,R.anim.group_animation); //创建动画对象,传入xml文件
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                button.startAnimation(animation); //启动动画
            }
        });
    }
} 
  • 效果图

深入浅析Android开发动画

1.2 逐帧动画

使用对象:View

原理:将动画拆分为帧的形式,且定义每一帧 = 每一张图片

本质:顺序播放一组预先定义好的图片

使用

  • 步骤1: 在res/anim文件夹中创建xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <animation-list
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="true" // 设置是否只播放一次,默认为false
     >
    
    // item = 动画图片资源;duration = 设置一帧持续时间(ms)
        <item android:drawable="@drawable/a0" android:duration="100"/>
        <item android:drawable="@drawable/a1" android:duration="100"/>
        <item android:drawable="@drawable/a2" android:duration="100"/>
        <item android:drawable="@drawable/a3" android:duration="100"/>
    </animation-list> 
  • 步骤二:在Java代码中设置

 Button button = findViewById(R.id.button);
                 button.setBackgroundResource(R.drawable.frame_animation);
                 
AnimationDrawable animationDrawable = (AnimationDrawable) button.getBackground();
  animationDrawable.start(); //启动动画 

优点:使用简单、方便

缺点:容易引起OOM,当使用大量 和尺寸较大的图片资源时。

二、属性动画

说明:属性动画(Property Animation)是在 Android 3.0API 11)后才提供的一种全新动画模式。

Q:为什么要提供属性动画?

  • View动画作用对象局限于View,而属性动画能作用于任意Java对象。
  • View动画只是改变了View的视觉效果,没有改变View的属性,属性动画可以改变对象的属性。
  • View动画效果单一,属性动画效果更加丰富。
View动画 属性动画
作用对象 View 任何对象,甚至没有对象
属性改变 没有改变属性 改变了属性
动画效果 效果单一 效果丰富

属性改变说明:比如将屏幕左上角的按钮通过补间动画移动到屏幕右下角,点击当前按钮位置(右下角)是没有效果的,实际上按钮还是停留在左上角,补间动画只是将按钮绘制到屏幕右下角,改变了视觉效果而已。

2.1 使用

同样的,属性动画可以在xml设置实,也可以在代码中设置实现。建议用代码实现:

  • 代码实现比较简单。
  • 属性的起始值有时候无法确定,需要动态地创建属性动画。

下面是组合动画旋转+平移实例。

Java 设置

 button = findViewById(R.id.button);
        // 步骤1:设置需要组合的动画效果
        // 平移动画

        ObjectAnimator translation = ObjectAnimator.ofFloat(button, "translationX", 0, 300);
        translation.setRepeatCount(0);

        // 旋转动画
        ObjectAnimator rotate = ObjectAnimator.ofFloat(button, "rotation", 0f, 360f);


        // 步骤2:创建组合动画的对象
        final AnimatorSet animSet = new AnimatorSet();

        // 步骤3:根据需求组合动画
        animSet.play(translation).with(rotate);
        // 步骤4:启动动画
		animSet.start(); 

XML设置

  • 步骤1:XML设置
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially" >
    // 表示Set集合内的动画按顺序进行
    // ordering的属性值:sequentially & together
    // sequentially:表示set中的动画,按照先后顺序逐步进行(a 完成之后进行 b )
    // together:表示set中的动画,在同一时间同时进行,为默认值

    <set android:ordering="together" >
        // 下面的动画同时进行
        <objectAnimator
            android:duration="2000"
            android:propertyName="translationX"
            android:valueFrom="0"
            android:valueTo="300"
            android:valueType="floatType" >
        </objectAnimator>
        
        <objectAnimator
            android:duration="3000"
            android:propertyName="rotation"
            android:valueFrom="0"
            android:valueTo="360"
            android:valueType="floatType" >
        </objectAnimator>
    </set>

       
</set> 
  • Java代码设置
AnimatorSet set = (AnimatorSet)AnimatorInflater.loadAnimator(this,R.anim.property_animator);
set.setTarget(button); //设置动画作用对象
set.start();//启动动画 
  • 效果图

深入浅析Android开发动画

2.2 插值器与估值器

类型 定义 作用 应用场景 备注
插值器 辅助动画实现的接口 设置属性值从初始值过渡到结束值的变化规律 实现非线性运动的动画效果 内置9种插值器/自定义插值器实现
估值器 辅助动画插值器的接口 设置属性值从初始值过渡到结束值的变化具体数值 协助插值器 实现非线性运动的动画效果 内置3种估值器/自定义估值器实现

插值器

 //xml设置
 android:interpolator="@android:anim/overshoot_interpolator"
 //Java代码设置
 Interpolator overshootInterpolator = new OvershootInterpolator();
 animation.setInterpolator(overshootInterpolator); 

深入浅析Android开发动画

深入浅析Android开发动画

估值器

  • 作用:根据当前属性改变的百分比计算出改变后的属性值
  • 常用的系统内置的估值器:
  • 整型估值器(IntEvaluator)
  • 浮点型估值器(FloatEvaluator)
  • Color属性估值器(ArgbEvaluator)
  • 仅针对于属性动画,View动画不需要类型估值器。是属性动画实现非匀速动画的重要手段。
  • 自定义插值器方法:实现 Interpolator / TimeInterpolator接口 ,然后复写getInterpolation()
  • 自定义估值器方法:实现TypeEvaluator接口,然后复写evaluate()

推荐一篇插值器估值器的详细用法Android 动画:你真的会使用插值器与估值器吗?(含详细实例教学)

2.3 监听器

 Animation.addListener(new AnimatorListener() {
          @Override
          public void onAnimationStart(Animation animation) {
              //动画开始时执行
          }
      
           @Override
          public void onAnimationRepeat(Animation animation) {
              //动画重复时执行
          }

         @Override
          public void onAnimationCancel()(Animation animation) {
              //动画取消时执行
          }
    
          @Override
          public void onAnimationEnd(Animation animation) {
              //动画结束时执行
          }
      });

// 特别注意:每次监听必须4个方法都重写。 

Q:有些时候我们并不需要监听动画的所有时刻,不想写太多代码怎么办?

采用动画适配器(AnimatorListenerAdapter)。

anim.addListener(new AnimatorListenerAdapter() {  
// 向addListener()方法中传入适配器对象AnimatorListenerAdapter()
// 由于AnimatorListenerAdapter中已经实现好每个接口
// 所以这里不实现全部方法也不会报错
    @Override  
    public void onAnimationStart(Animator animation) {  
    // 如想只想监听动画开始时刻,就只需要单独重写该方法就可以
    }  
}); 

三、总结

深入浅析Android开发动画

ObjectAnimatorValueAnimator类的区别:

  • ValueAnimator 类是先改变值,然后 手动赋值 给对象的属性从而实现动画;是 间接 对对象属性进行操作;
  • ObjectAnimator 类是先改变值,然后 自动赋值 给对象的属性从而实现动画;是 直接 对对象属性进行操作;

ValueAnimator类自动赋值的逻辑:

  1. 初始化时,如果属性的初始值没有提供,则调用属性的 get()进行取值;
  2. 当 值 变化时,用对象该属性的 set()方法,从而从而将新的属性值设置给对象属性。
  • ObjectAnimator 类针对的是任意对象 & 任意属性值,并不是单单针对于View对象
  • 如果需要采用ObjectAnimator 类实现动画效果,那么需要操作的对象就必须有该属性的set() & get()
  • 同理,针对上述另外的三种基本动画效果,View 也存在着setRotation()getRotation()setTranslationX()getTranslationX()setScaleY()getScaleY()set() & get()

本文参考自:

本文地址:https://blog.csdn.net/qq_44830568/article/details/109059720

相关标签: Android java