美文网首页Android开发
Android动画(上)--补间动画、帧动画

Android动画(上)--补间动画、帧动画

作者: 未远可追 | 来源:发表于2018-08-03 17:57 被阅读1次

    Android动画分类

    Android的动画可以分为三类:补间动画(Tween Animation)、帧动画(Frame Animation)、属性动画(Property Animation)。

    三种动画的区别

    补间动画又称View动画, 它通过对View对象不断做图形变化(缩放、平移、透明度、旋转)来产生动画效果,是一种渐进式动画。它产生的效果只是视觉上的变化,View的属性并没有发生改变。

    帧动画是通过顺序播放一组图片而产生动画效果,但是图片过多过大的时候容易导致内存溢出,而且很占资源。

    属性动画通过改变view对象的属性从而达到动画效果。

    补间动画

    补间动画有缩放、平移、旋转、透明度四种动画效果,分别对应Animation的ScaleAnimation、TranslateAnimation、RotateAnimation、AlphaAnimation这四个子类。

    补间动画的使用方式有两种,一种是在res/anim/目录下通过 xml文件来定义动画 后在代码中调用,另一种通过 代码动态直接定义动画 调用。

    1.缩放动画

    顾名思义缩放动画就是对View进行逐步缩放来达到缩放的动画。

    第一种使用方式:

    在xml文件中使用的标签为<scale> </>定义缩放动画,然后代码调用。

    <?xml version="1.0" encoding="utf-8"?>
    <!--fromXScale fromYScale  toXScale toYScale 这几个属性的值是以view的宽高为基准-->
    <!--fromXScale="0.5"  toXScale="2.0" 代表从自身宽度的0.5倍放大到自身宽度的2.0倍-->
    <!--fromYScale="1.0"  toYScale="2.0" 代表从自身高度的1倍放大到自身高度的2.0倍-->
    <!--pivotX,pivotY是缩放中心的坐标  有三种形式-->
    <!--第一种固定值,点的坐标等于控件左上角的坐标加上pivotX,pivotY的值-->
    <!--第二种以百分号结束 如pivotX="50%",代表缩放基点x的坐标为控件左上角的x坐标加上控件宽度的一半-->
    <!--第三种以百分号加p结束 如pivotY="50%p",表示相对于控件的父控件的定位-->
    <!--android:interpolator 插值器  用来控制动画的快慢变化-->
    
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
           android:interpolator="@android:anim/accelerate_decelerate_interpolator"
           android:duration="2000"
           android:fromXScale="1.0"
           android:fromYScale="1.0"
           android:pivotX="100"
           android:pivotY="100"
           android:toXScale="2.0"
           android:toYScale="2.0">
    </scale>
    
    
    基点.png

    定义好xml动画后,紧接着动态代码中使用AnimationUtils将xml文件加载成一个Animation,然后调用view的startAnimation方法即可。

            Button button =(Button) findViewById(R.id.button);
    
            Animation scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_animation);
            scaleAnimation .setDuration(2000);//动画持续时长  可在这设置  也可在xml文件中定义
            mScaleAnimation.setFillAfter(true); // 动画结束后保持最后的状态 
            BounceInterpolator bounceInterpolator = new BounceInterpolator();  // 在动画结束时有回弹的插值器
            mAnimation.setInterpolator(bounceInterpolator);// 设置插值器 也可在xml文件中定义
    
            button.startAnimation(scaleAnimation1);// 开始动画  对button进行缩放
           
    
    第二种使用方式:

    代码中直接初始化一个ScaleAnimation对象,查看源码知道构造方法一共有四个,需要解释的是pointXType,pointYType的值一共有三个。

      //源码
        public static final int ABSOLUTE = 0;  // pointType传入该值则对应xml文件中的第一种形式标
        public static final int RELATIVE_TO_SELF = 1; // 相对控件本身的坐标 对应xml文件中 以百分号 %结束
        public static final int RELATIVE_TO_PARENT = 2; //  相对父布局的坐标  对应xml文件中以 %p 结束
    
        public ScaleAnimation(Context context, AttributeSet attrs) {
        }
        public ScaleAnimation(float fromX, float toX, float fromY, float toY) {
            // 该构造方法 pivotX,pivotY都为零   
        }
        public ScaleAnimation(float fromX, float toX, float fromY, float toY,
                float pivotX, float pivotY) {
            // 该构造方法 会给pivotType 赋默认值 ABSOLUTE    绝对坐标 
            mPivotXType = ABSOLUTE;
            mPivotYType = ABSOLUTE;
            省略 .....
        }
        public ScaleAnimation(float fromX, float toX, float fromY, float toY,
                int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) {
          // 传入不同的pivotType值则对应不同的规则
            省略 .....
        }
    
    
            //pviontX,pivotY都为0
            ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f);//pviontX,pivotY为绝对
    
             //等同于xml定义中第一种方式 pivotX和pivotY都为100
            ScaleAnimation scaleAnimation1 = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f,
                    Animation.ABSOLUTE, 100, Animation.ABSOLUTE, 100);
    
            // 等同于xml定义中的第二种方式,相对控件本身的坐标
            ScaleAnimation scaleAnimation2 = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f,
                    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    
            //等同于xml定义中的第三种方式,相对父布局的坐标
            ScaleAnimation scaleAnimation3 = new ScaleAnimation(1.0f, 2.0f, 1.0f, 2.0f,
                    Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.5f);
    
    
            Button button =(Button) findViewById(R.id.button);
            scaleAnimation1.setDuration(2000);// 动画持续时间为2000ms
            scaleAnimation1.setFillAfter(true);// 保持动画最后的展示效果
            BounceInterpolator bounceInterpolator = new BounceInterpolator();  // 在动画结束时有回弹的插值器
            mAnimation.setInterpolator(bounceInterpolator);// 设置插值器 也可在xml文件中定义
            mScaleAnimation.setStartOffset(1000); // 动画延时一秒后执行
    
    
            button.startAnimation(scaleAnimation1);//开始动画 
    
    2.平移动画

    xml文件中使用<translate></>标签定义

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!--fromXDelta 起始点x的坐标  和scale中一样,有三种表示形式(数值,%,%p)-->
        <!--toXDelta   结束点X的坐标  同上也有三种表示形式-->
        <!--fromYDelta 起始点Y的坐标  同上规律-->
        <!--toYDelta   结束点Y的坐标  同上规律-->
        <translate
            android:duration="2000"
            android:fromXDelta="0.0"
            android:fromYDelta="-100%p"
            android:toXDelta="0.0"
            android:toYDelta="0.0"/>
    </set>
    
    //        ======平移动画=====
            mTranslateAnimation = AnimationUtils.loadAnimation(this, R.anim.translate_animate);
            mTranslateAnimation.setDuration(2000);
            mTranslateAnimation.setFillAfter(true);
    
    //动态代码创建
            mTranslateNewAnimation = new TranslateAnimation(Animation.ABSOLUTE, 0.0f, Animation.ABSOLUTE, 0.0f,
                    Animation.RELATIVE_TO_SELF, -2.0f, Animation.ABSOLUTE, 0.0f);
            mTranslateNewAnimation.setDuration(4000);
    
    透明度动画

    xml文件中使用<alpha></>标签定义

    <?xml version="1.0" encoding="utf-8"?>
    <!--fromAlpha 最开始的透明度  1表示不透明 0表示全透明,值只能在0.0到1.0之间变化-->
    <alpha xmlns:android="http://schemas.android.com/apk/res/android"
           android:duration="2000"
           android:fillAfter="true"
           android:fromAlpha="1.0"
           android:toAlpha="0.0"/>
    
    //        =======渐变动画=====
            mAlphaAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha_animation);//加载动画
            mAlphaAnimation.setDuration(1000);
            mAlphaAnimation.setFillAfter(true);
      
            //动态代码创建
            mAlphaNewAnimation1 = new AlphaAnimation(1.0f, 0.0f);
            mAlphaNewAnimation1.setDuration(2000);
            mAlphaNewAnimation1.setFillAfter(false);
    
            button.startAnimaiton(mAlphaAnimation );
    
    旋转动画

    xml文件中使用<ratate></>标签定义

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <!--fromDegrees 旋转的开始角度,正数代表顺时针度数,负数代表逆时针度数-->
        <!--toDegrees   旋转结束角度 -->
        <!--pivotX,pivotY的规律同其他动画规律一致-->
        <rotate
            android:fromDegrees="0"
            android:pivotX="50%p"
            android:pivotY="50%p"
            android:toDegrees="180"/>
    </set>
    
    // ===============  旋转动画 ===============
           //加载xml动画
            mRotateAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate);
            mRotateAnimation.setDuration(2000);
            mRotateAnimation.setFillAfter(true);
            mRotateAnimation.setStartOffset(1000);//执行前的等待时间
            button.startAnimation(mRotateAnimation );// 开始动画,对button进行旋转
    
    
          //动态创建
            mRotateNewAnimation = new RotateAnimation(0.0f, 180f, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.5f);
            mRotateNewAnimation.setDuration(2000);
            button.startAnimation(mRotateNewAnimation );// 开始动画,对button进行旋转
    

    Frame帧动画

    Frame帧动画就是播放一组图片来达到动画的效果。在res/drawable目录下创建drawable resource xml资源文件,使用 <animation-list></>标签。

    <?xml version="1.0" encoding="utf-8"?>
    <animation-list
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false">
        <!--oneshot 是否只播放一次-->
        <!--duration 单张图片持续时间-->
    
        <item android:drawable="@mipmap/image1" android:duration="200"/>
        <item android:drawable="@mipmap/image2" android:duration="200"/>
        <item android:drawable="@mipmap/image3" android:duration="200"/>
        <item android:drawable="@mipmap/image4" android:duration="200"/>
        <item android:drawable="@mipmap/image5" android:duration="200"/>
    </animation-list>
    

    因为帧动画是播放一张一张的图片,所以需要ImageView作为载体,在布局文件中引用。

            <ImageView
                android:layout_marginTop="30dp"
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/frame_animation"/>
    

    代码中通过ImageView的getDrawable方法得到AniAnimationDrawable。

            mImageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                  // 得到 AnimationDrawable 
                    AnimationDrawable animationDrawable = (AnimationDrawable) mImageView.getDrawable();
                    animationDrawable.setOneShot(false); // 循环播放  为true则只播放一次
    
                    if (animationDrawable.isRunning()){
                        animationDrawable.stop(); // 停止动画 
                    }else {
                        animationDrawable.start(); // 开始动画
                    }
                }
            });
    

    相关文章

      网友评论

        本文标题:Android动画(上)--补间动画、帧动画

        本文链接:https://www.haomeiwen.com/subject/ixarvftx.html