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

安卓动画全解:补间动画(视图动画)、布局动画、属性动画、逐帧动画。动画Animation属性、Alpha属性、Scale属性、Translate属性、Rotate属性,动画集AnimationSet

程序员文章站 2022-03-02 08:18:17
...

全栈工程师开发手册 (作者:栾鹏)

安卓教程全解

安卓动画全解:补间动画(视图动画)、布局动画、属性动画、逐帧动画。

主要内容包含:动画Animation属性、Alpha属性、Scale属性、Translate属性、Rotate属性,动画集AnimationSet,动画的两种定义形式(xml中定义和java中定义),应用两种形式的动画和应用动画集。

动画的属性

Animation的属性

JAVA方法                              XML属性                           解释
setDetachWallpaper(boolean)         android:detachWallpaper         是否在壁纸上运行
setDuration(long)                   android:duration                设置动画持续时间,单位为毫秒
setFillAfter(boolean)               android:fillAfter               控件动画结束时控件是否保持动画最后状态
setFillBefore(boolean)              android:fillBefore              控件动画结束时控件是否还原到开始动画前的状态
setFillEnable(boolean)              android:fillEnable(boolean)     与android:fillBefore效果相同
setInterpolator(boolean)            android:interpolator            设置插值器(指定的动画效果,如:回弹等)
setRepeatCount(int)                 android:repeatCount             重复次数
setRepeatMode(int)                  android:repeatMode              重复类型:reverse倒序回放、restart从头播放
setStartOffset(long)                android:startOffset             调用start函数后等待开行运行的时间,单位为毫秒
setZadjustment(int)                 android:zAdjustment             表示被设置动画的内容运行时在Z轴的位置(top/bottom/normal),默认为normal

由于Animation类是其抽象父类,那么我们在使用补间动画无论是哪一种都已经具备了以上属性。
下面是每一种补间动画的特有属性:

Alpha属性

JAVA方法                                  XML属性                       解释
AlphaAnimation(float fromAlpha,…)       android:fromAlpha           动画开始的透明度(0.01.00.0是全透明,1.0是不透明)
AlphaAnimation(…, float toAlpha)        androdi:toAlpha             动画结束的透明度(同上)

Rotate属性

JAVA方法                                      XML属性                       解释
RotateAnimation(float fromDegrees, …)       android:fromDegress         旋转开始角度,正代表顺时针度数,负代表逆时针度数
RotateAnimation(…, float toDegress)         android:toDegress           旋转结束角度(同上)
RotateAnimation(…, …, float pivotX, …)     android:pivotX              缩放起点X坐标(数值、百分数、百分数p,譬如50表示以当前View左上角坐标加50px为初始点、50%表示以当前View的左上角加上当前View宽高的50%做为初始点、50%p表示以当前View的左上角加上父控件宽高的50%做为初始点)
RotateAnimation(…, …, …, pivotY)            android:pivotY              缩放起点Y坐标(同上)

Scale属性

JAVA方法                                      XML属性                           解释
ScaleAnimation(float fromX, …)              android:fromXScale          初始X轴缩放比例,1.0表示无变化
ScaleAnimation(…, float toX)                android:toXScale            结束X轴缩放比例
ScaleAnimation(…, …, float fromY, …)       androd:fromYScale           初始Y轴缩放比例
ScaleAnimation(…, …, …, float toY)         android:toYScale             结束Y轴缩放比例
ScaleAnimation(…, float pivotX, …)          android:pivotX              缩放起点X轴坐标(同上)
ScaleAnimation(…, float pivotY)              android:pivotY             缩放起点Y轴坐标(同上)

Translate属性

JAVA方法                                              XML属性                       解释
TranslateAnimation(float fromXDelta, …)         android:fromXDelta          平移起始点X轴坐标
TranslateAnimation(…, float toXDelta)           android:toXDelta            平移结束点X轴坐标
TranslateAnimation(…, float fromYDelta, …)      android:fromYDelta          平移起始点Y轴坐标
TranslateAnimation(…, float toYDelta)           android:toYDelta            平移结束点Y轴坐标

AnimationSet属性

AnimationSet类比较特殊,因为该类是以上4类的组合容器管理类,没有自己特有的属性,它的属性继承自它的父类:Animation。
我们在使用的时候需要注意,当我们在对set标签设置属性的时候,那么其标签下的所有控件都会产生影响。

补间动画(视图动画):

补间view动画(改变外观,不改变属性):窗口间切换、窗口内布局间的切换、相同view的不同内容间的切换、向用户提供反馈(进度、晃动)

定义、应用补间动画(视图动画)的形式

动画的定义有两种形式,一种是在xml中设计动画,一种是在java中设计动画。

1、在res/anim下定义一个补间动画文件popin.xml

<?xml version="1.0" encoding="utf-8" ?>
<!-- 补间view动画(改变外观,不改变属性):窗口间切换、窗口内布局间的切换、相同view的不同内容间的切换、向用户提供反馈(进度、晃动) -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:interpolator="@android:anim/accelerate_interpolator">
  <!-- 定义一个差值view动画 -->
  <scale
    android:fromXScale="1.0" android:toXScale="0.0"
    android:fromYScale="1.0" android:toYScale="0.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="10"
    android:repeatMode="reverse"
    android:duration="1000"  />
</set>


<!-- 
设置每一个子动画的开始偏移时间和持续时间很重要,否则就会同时开始和结束
动画可设置的属性,已在前面给出
 -->

2、在代码中应用xml中定义的补间动画

      Animation myanimation = AnimationUtils.loadAnimation(context, R.anim.popin);  
      myanimation.setRepeatMode(Animation.REVERSE);  //设置动画模式,RESTART动画正向,REVERSE动画反向
      myanimation.setRepeatCount(500); //设置动画循环次数,Animation.INFINITE无限次,对于xml中的动画,这个属性必须在xml中设置才有效
      myanimation.setAnimationListener(new AnimationListener() {   //设置动画监听器    
        @Override
        public void onAnimationStart(Animation animation) {
            //动画开始时执行处理
            Log.v("补间动画", "动画开始");
        }
        @Override
        public void onAnimationRepeat(Animation animation) {
            //动画重复时执行处理
            Log.v("补间动画", "动画重复");
        }
        @Override
        public void onAnimationEnd(Animation animation) {
            //动画完成后执行处理 
            Log.v("补间动画", "动画结束");  //最后一遍动画结束
        }
      });

      //应用动画
      TextView tv = (TextView) findViewById(R.id.activity1_text1);
      tv.startAnimation(myanimation);  //应用动画到控件

3、在java代码中应用自定义补间动画

下面简单介绍了透明动画,旋转动画,缩放动画,位移动画。动画可设置的属性已在前面给出。

//自定义透明度动画
  public void alpha(View v){
        AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
        anim.setDuration(1000);
        anim.setRepeatCount(10);
        v.startAnimation(anim);
    }
  //自定义旋转动画
    public void rotate(View v){
        RotateAnimation anim = new RotateAnimation(0.0f, -360f, v.getWidth()/2, v.getHeight()/2);
        anim.setDuration(1000);
        v.startAnimation(anim);
    }
   //自定义缩放动画
    public void scale(View v){
        ScaleAnimation anim = new ScaleAnimation(1.0f, 0.0f, 0.0f, 1.0f, v.getWidth() / 2, v.getHeight() / 2);
        anim.setDuration(1000);
        v.startAnimation(anim);
    }
   //自定义位移动画
    public void translate(View v){
        TranslateAnimation anim = new TranslateAnimation(0.0f, 10.0f, 100f, 200f);
        anim.setDuration(1000);
        v.startAnimation(anim);
    }

应用补间动画合集

我们知道如何设置和应用xml中的动画和java中自定义动画后,我们就可以来为控件或布局应用动画合集了。
在动画合集中可以添加xml中的动画,也可以添加java代码中设计的动画。

    //应用动画集合
    public void animationset(View v) {
          AnimationSet animationSet = new AnimationSet(true);
          Animation anim1 = AnimationUtils.loadAnimation(context, R.anim.popin);  
          AlphaAnimation anim2 = new AlphaAnimation(0.0f, 1.0f);
          anim2.setDuration(1000);
          anim2.setRepeatCount(10);
          animationSet.addAnimation(anim1);
          animationSet.addAnimation(anim2);
          v.startAnimation(animationSet);  //应用动画集合
    }

布局动画

布局动画,可以用来为View Group添加动画,按照预定的顺序和一个动画或动画集合应用到viewGroup的每一个子view中

应用布局动画也有两种形式。

1、一种是在res/anim下只创建补间动画的xml,如上面的popin.xml,然后在java中将这种补间动画,转化为布局动画应用到View Group

  //应用布局动画,应用到viewgroup中
  public void apply_layoutanimation(ViewGroup view) {
      //通过加载XML动画设置文件来创建一个Animation对象;
      Animation anim=AnimationUtils.loadAnimation(this, R.anim.popin);
      //得到一个LayoutAnimationController对象;
      LayoutAnimationController controller=new LayoutAnimationController(anim);
      //设置控件显示的顺序;
      controller.setOrder(LayoutAnimationController.ORDER_REVERSE);  //对于
      //设置每个控件动画的间隔时间,单位秒;
      controller.setDelay(0.3f);
      //为View Group设置LayoutAnimationController属性;
      view.setLayoutAnimation(controller);
  }

2、另一种方式处理在res/anim下创建补间动画的xml,还在res/anim下创建布局动画的xml,然后在UI的xml中应用布局动画。这里除了上面的popin.xml,再创建一个popinlayout.xml的布局动画

<?xml version="1.0" encoding="utf-8" ?>
<!-- 布局动画,可以用来为View Group添加动画,按照预定的顺序和一个动画或动画集合应用到viewGroup的每一个子view中 -->
<layoutAnimation
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:delay="0.3"
  android:animationOrder="random"
  android:animation="@anim/popin"
/>

<!-- 
Android:delay  子类动画时间间隔 (延迟)   70% 也可以是一个浮点数 如“1.2”等 
android:animationOrder="random"   子类的显示方式 normal    0   默认,reverse  1 倒序,random 2     随机
android:animation="@anim/slide_right" 表示子类显示时的具体动画是什么
其中delay的单位为秒;animation为设置动画的文件。animationOrder为进入方式
-->

布局动画的xml不能再Java中引入,必须在窗口的UI文件中引入使用

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/activity1_linearlayout1"
    android:layoutAnimation="@anim/popinlayout"  >
</LinearLayout>

逐帧动画

逐帧动画,选项图像顺序播放的功能。逐帧动画的xml文件存放在res/drawable文件夹下。

首先在res/drawable文件下建一个逐帧动画的anim3.xml文件

<?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/img1" android:duration="500" />
        <item android:drawable="@drawable/img2" android:duration="500" />
        <item android:drawable="@drawable/img3" android:duration="500" />
</animation-list>

<!-- 
在java中调用  
imageView1.setBackgroundResource(R.drawable.anim3);
AnimationDrawable androidanimation = (AnimationDrawable)imageView1.getBackground();
androidanimation.start();
-->

在java中调用逐帧动画,并应用到ImageView中。逐帧动画只能放在ImageView中。

  public void apply_animation_list(ImageView imageView) {
      imageView.setBackgroundResource(R.drawable.anim3);

      //通过实例控制动画运行
      AnimationDrawable animation=(AnimationDrawable)imageView.getBackground();
      animation.start();  //启动播放
      //animation.stop();  //停止播放
  }

属性动画

属性动画也有两种定义方式

1、在res/animator文件夹下定义属性动画的xml,这里命名为anim1.xml

<?xml version="1.0" encoding="utf-8" ?>
<!-- 属性动画 -->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="alpha"
    android:duration="1000"
    android:valueFrom="0.0"
    android:valueTo="1.0"     
    android:valueType="floatType"
    android:repeatCount="-1"
    android:repeatMode="reverse"
/>



<!-- 
可以设置动画集
<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>

 -->

在java中应用在xml中定义的属性动画

public void apply_objectAnimator(View view)  
    {  
         //应用动画资源
         Animator animation=AnimatorInflater.loadAnimator(context, R.animator.anim1);
         animation.setDuration(500);   //默认为300
         animation.setTarget(view);   //设置目标

        //设置插值器
         //AccelerateDecelerateInterpolator开始和结束时速度变换缓慢,在中间的时候加速
         //AccelerateInterpolator开始时速度变化较慢,在中间的时候加速
         //AnticipateInterpolator开始的时候向后,然后再向前急冲
         //AnticipateOvershootInterpolator开始的时候向后,然后再向前急冲一定的值后,最后回到最终的值
         //BounceInterpolator动画结束时弹起
         //DecelerateInterpolator开始时速度变化较快,然后减速
         //LinearInterpolator速度的变化是一个常量
         //OvershootInterpolator开始向前急冲,超过最终的值,然后再回来
         animation.setInterpolator(new LinearInterpolator());  

         //应用监听器
         animation.addListener(new AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                Log.v("属性动画", "动画开始");
            }
            @Override
            public void onAnimationRepeat(Animator animation) {
                Log.v("属性动画", "动画重复");
            }
            @Override
            public void onAnimationEnd(Animator animation) {
                Log.v("属性动画", "动画结束");
            }
            @Override
            public void onAnimationCancel(Animator animation) {
                Log.v("属性动画", "动画取消");
            }
        });
         animation.start(); //启动
    }  

2、在java中定义同时应用属性动画

    public void apply_objectAnimator1(View view) {
         ObjectAnimator animator1 =ObjectAnimator.ofFloat(view, "rotationX", 0.0F, 360.0F);   //参数:控件,动画属性,起始状态,终止状态
         ObjectAnimator animator2 =ObjectAnimator.ofFloat(view, "rotationX", 360.0F);  //参数:控件,动画属性,终止状态(从当前状态开始)

         animator1.setDuration(2000);  
         animator1.start();  

         //动画的属性和参数内容较多
         //ObjectAnimator.ofFloat(view,"rotation",0,180,0);  //中心旋转,0度到180度再到0度
         //ObjectAnimator animator = ObjectAnimator.ofFloat(view,"rotationX",0,270,0);    //中心轴为x轴的旋转,从0度到270度再到0度
         //ObjectAnimator animator = ObjectAnimator.ofFloat(view,"rotationY",0,180,0);    //中心轴为y轴的旋转,从0度到180度再到0度
         //ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationX", 0, 200, -200,0);  //当前位置向右200像素,再移动到距离原点左侧200的位置,最后回到原点; 
         //ObjectAnimator animator = ObjectAnimator.ofFloat(view, "translationY", 0, 200, -100,0);  //当前位置向下200像素,再移动到距离原点上方200的位置,最后回到原点; 
        //ObjectAnimator animator = ObjectAnimator.ofFloat(view, "scaleX", 0, 3, 1);  //横向上,从0倍放大到3倍,然后再还原到1倍的原始状态。
        //ObjectAnimator animator = ObjectAnimator.ofFloat(view, "scaleY", 0, 3, 1);  //纵向上,从0倍放大到3倍,然后再还原到1倍的原始状态。
    }

应用属性动画集

属性动画集中也使用AnimatorSet,每一个动画可以是xml中定义的,也可以是java中定义的。要使用两次一个动画,需要创建两个动画对象。

    public void animationset_object(View view) {
        Animator animation1=AnimatorInflater.loadAnimator(context, R.animator.anim1);  //获取xml中定义的动画
        Animator animation2=AnimatorInflater.loadAnimator(context, R.animator.anim1);  //一个动画可以多次使用
        ObjectAnimator animation3 =ObjectAnimator.ofFloat(view, "rotationX", 360.0F);  //java中自定义动画
        animation1.setTarget(view);   //设置目标
        animation2.setTarget(view);   //设置目标
        AnimatorSet myset=new AnimatorSet();
        myset.play(animation1).before(animation2);   //设置前后顺序
        myset.play(animation3).with(animation2);  //同时播放,myset.playTogether(animation1, animation3);
        myset.play(animation2).after(animation1);  //设置前后顺序
        myset.setDuration(1000);  //设置周期

        myset.start();   //启动动画集合
    }