Android动画学习一

来源:互联网 发布:gbase数据库 编辑:程序博客网 时间:2024/05/22 03:28

android动画分类

1、视图动画        - 补间动画        - 帧动画2、属性动画(3.0之后)   

视图动画

  • 平移

  • 旋转

  • 缩放

  • 透明度

  • 帧动画

对于上述动画我们都可以使用XML实现或者使用代码实现。为了演示充分,前两种我们通过XML形式实现,后面两种我们通过代码实现。(两种相比较更推荐以XML形式去实现动画。这种方式写动画效果更简单易懂)

XML实现平移

首先检查res下面是否有anim文件夹,如果没有的话,新建一个。

<?xml version="1.0" encoding="utf-8"?><!--平移动画的xml形式实现--><!--下面这段代码的意思是在1s钟内将View从当前位置向右移动300像素--><set xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="1000"    android:interpolator="@android:anim/overshoot_interpolator">    <translate        android:fromXDelta="0"        android:fromYDelta="0"        android:toXDelta="300"        android:toYDelta="0"        android:repeatCount="infinite">    </translate>    <!-- android:repeatCount="infinite" 无限重复 只能在子节点中单独设置--></set>

开启平移

translateView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.translate_animation))

XML实现旋转

<?xml version="1.0" encoding="utf-8"?><!--旋转动画的xml形式实现--><set xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="1000"    android:interpolator="@android:anim/accelerate_decelerate_interpolator">    <rotate        android:pivotY="50%"        android:pivotX="50%"        android:fromDegrees="0"        android:toDegrees="360"        android:repeatCount="infinite">    </rotate>    <!--pivotX,pivotY的可选数值有三种:-->    <!--缩放起点X轴坐标,可以是数值、百分数、百分数p -->    <!--三种样式,比如 50、50%、50%p,当为数值时,表示在当前View的左上角-->    <!--即原点处加上50px,做为起始缩放点;如果是50%,表示在当前控件的左上角加上自己宽度的50%做为起始点;-->    <!--如果是50%p,那么就是表示在当前的左上角加上父控件宽度的50%做为起始点x轴坐标。(具体意义,后面会举例演示)-->    <!-- android:repeatCount="infinite" 无限重复 只能在子节点中单独设置--></set>

开启旋转

rotateView.startAnimation(AnimationUtils.loadAnimation(this,R.anim.rotate_animation))

代码实现缩放和透明度动画

        //缩放动画        val scaleAnimation = ScaleAnimation(0f,1f,1f,1f)        scaleAnimation.duration = 1000        scaleAnimation.repeatCount = Animation.INFINITE        scaleView.startAnimation(scaleAnimation)        //透明度动画        val alphaAnimation = AlphaAnimation(0f,1f)        alphaAnimation.duration = 2000        alphaAnimation.repeatCount = Animation.INFINITE        alphaView.startAnimation(alphaAnimation)

视图动画的效果1

这里写图片描述

上面我们有提到视图动画大致可以细分到五种,我们上面实现了基本的四种,现在是另外一种。

帧动画

帧动画其实就是对于一组图片的快速播放。这个实现也比较简单。它的实现过程可以分为如下几个步奏:

1、新建animation类型的drawble2、以此drawble设置为某一个view的src3、在代码中得到View的drawble并进行类型转换到AnimationDrawable4、drawble.start()

1、新建drawable:frame_animation.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/a"        android:duration="200">    </item>    <item        android:drawable="@drawable/b"        android:duration="200">    </item>    <item        android:drawable="@drawable/c"        android:duration="200">    </item>    <item        android:drawable="@drawable/d"        android:duration="200">    </item>    <item        android:drawable="@drawable/e"        android:duration="200">    </item>    <item        android:drawable="@drawable/f"        android:duration="200">    </item>    <item        android:drawable="@drawable/g"        android:duration="200">    </item></animation-list>

2、将它设置为一个view的background

        <ImageView            android:id="@+id/frameView"            android:layout_width="100dp"            android:layout_height="100dp"            android:layout_margin="@dimen/activity_vertical_margin"            android:src="@drawable/frame_animation"/>

3、在代码中转换drawable

 val frameAnimation = frameView.drawable as AnimationDrawable

4、开启动画

 frameAnimation.start()

AnimationSet

我们上面谈到Animation的时候都是对view使用单一的动画效果,事实上我们可以对View的效果进行我们想要的 叠加

案例:平移时旋转
这里我们通过XML方式实现

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"    android:duration="1000"    android:interpolator="@android:anim/accelerate_decelerate_interpolator">    <rotate        android:pivotY="50%"        android:pivotX="50%"        android:fromDegrees="0"        android:toDegrees="360"        android:repeatCount="infinite">    </rotate>    <translate        android:fromXDelta="0"        android:fromYDelta="0"        android:toXDelta="300"        android:toYDelta="0"        android:repeatCount="infinite">    </translate></set>

视图动画的效果2

(靠下下的两个)
这里写图片描述

(这个不知道传上去就不动了,实际上都是可以动的)

属性动画

在Android3.0之前是没有属性动画的。属性动画的提出很大一部分原因是视图动画的局限性:视图动画只是改变视图内容的位置,而不改变视图本身位置。
这句话的意思是什么呢?
假如你把一个button通过视图动画向右平移了100px,并且为动画设置了fillAfter。
当你开启此动画,这个button在视觉上就会从以前的位置移动到新位置。但是你会发现当button位置移动之后,button的点击事件“失效”了。实际上不是失效了,而是button还在以前的位置,只是在视觉上button换了新位置,而这个视觉上的新位置不能相应button的点击事件。所以,属性动画来了。(关于这点请读者自行验证,我以前遇到过这种问题,但是那时候不知道这些)

ObjectAnimator

ObjectAnimator是属性动画里面最重要的一个实行类,创建一个ObjectAnimator只需要通过他的静态工厂类直接返回一个ObjectAnimator对象。

构造一个属性动画所需参数如下:

1、要操作的View2、要操作的属性3、属性变化的取值数组(是可变数组参数)

举个例子:属性动画实现平移

        val animator = ObjectAnimator.ofFloat(propTranView,"translationX",0f,300f)        animator.duration = 1000        animator.repeatCount = Animation.INFINITE        animator.start()

关于ObjectAnimator的使用有一个很重要的事:我们想要操作的参数必须具有set和get,因为对于属性动画,系统内部会通过java反射来操作set函数,从而真实的改变对象的属性值。
如果一个属性没有set和get函数的话,我们也可以使用属性动画。只不过要换一种方式。

自定义属性类或者包装类来间接的给这个属性增加set或者get方法
举例:属性动画更改View自身大小(view的width和height不存在set函数)

   companion object {        class WrapperView(val targetView:View){            fun getWidth():Int{                return targetView.width            }            fun setWidth(width:Int){                targetView.layoutParams.width = width                targetView.requestLayout() //请求重新layout            }        }    }
        //属性动画:更改View自身宽度        val wrapper = WrapperView(propScaleView)        val animator1 = ObjectAnimator.ofInt(wrapper,"width",500)        animator1.duration = 1000        animator1.repeatCount = Animation.INFINITE        animator1.start()

PropertyValuesHolder

它的作用类似视图动画里面的AnimationSet,当动画要作用于一个对象的多个属性时,我们可以使用PropertyValuesHolder来实现。

案例:平移时旋转

        //属性动画:平移时旋转        val pvh1 = PropertyValuesHolder.ofFloat("translationX",300f)        val pvh2 = PropertyValuesHolder.ofFloat("rotation",360f)        val animator2 = ObjectAnimator.ofPropertyValuesHolder(propMultiView,pvh1,pvh2)        animator2.duration = 1000        animator2.repeatCount = Animation.INFINITE        animator2.start()

ValueAnimator

ValueAnimator是ObjectAnimator的父类。它本身并不提供动画效果,但是对象的属性数值变化是由它来控制。调用者根据它产生的一系列数值来控制动画的实现。
下面是ValueAnimator的一个基本使用方法:

        //属性动画:通过ValueAnimator        val animator3 = ValueAnimator.ofFloat(0f,100f)        animator3.setTarget(propValueView)        animator3.duration = 1000        animator3.repeatCount = Animation.INFINITE        animator3.start()        animator3.addUpdateListener { animator:ValueAnimator->            //使用数值        }

属性动画效果图

这里写图片描述

参考:

Android群英传

Android开发艺术探索

Android分别通过代码和xml实现动画效果

自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法

原创粉丝点击