Android动画学习一

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类型的drawble
2、以此drawble设置为某一个view的src
3、在代码中得到View的drawble并进行类型转换到AnimationDrawable
4、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、要操作的View
2、要操作的属性
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属性及用法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值