乐趣区

Android日常学习Android视图动画View-Animation

介绍

视图动画主要有两种:

一、Tween Animation译为“补间动画”
1、scale译为“规模、比例”,是对 View 进行特定范围的缩放
2、alpha 通过改变 View 的透明度实现 View 隐现的效果
3、translate 译为 ” 转移 ”,是对 View 进行位置的移动
4、rotate 译为“旋转”,是让 View 围绕特定的点进行旋转
PS:所有 View 的移动、隐藏、旋转仅仅是看到的动画效果,实际 View 的位置 / 大小 / 比例并没有发生本质上的改变(比如说 View 的位置通过动画进行移动后你注册的点击事件还是需要点击到 View 的原始位置才可以被触发)。

二、Frame Animation译为逐帧动画
这个比较容易理解就是将多个具有特定连贯动作的图片在短时间内进行快速的切换达到动画的效果,本质上所有的动画效果都是这种思想。

如何创建视图动画文件目录

动画文件要存放在 res/anim 文件夹下,访问时采用 R.anim.XXX 的方式。默认是没有这个文件夹的需要手动创建(右键 res 目录 –>New–>Android Resource Directory–> 确定。)

动画文件的创建方式为: 右键 anim 文件夹选择 new, 然后点击 Animation Resource file,选择动画类型即可创建。

输入后会自动提示动画名称,然后输入名称,确定即可。

scale(缩放) 动画

这个动画参数相对来说比较多,就我个人而言在学习这个动画的时候花费时间是最长的。

这个动画主要是实现 View 的缩放,首先要想,要实现一个缩放的动画首先要确定什么参数 / 信息 (好比说想切割一张特定大小的纸张要确定宽和高一样),那么第一个就是要确定要围绕哪个点(pivot) 进行缩放。

还需要知道在动画开始 (from) 时 View 的大小 (比例),以及动画结束(to) 时 View 要处于的大小(比例)。就是要确定以下六个参数才可以完成一次缩放动画。

X 则指定控件的宽度,Y 则指定控件的高度,值越大则控件所占位置越大。

Android 坐标从左上角开始算起。

其中 fromXScaletoXScalefromYScaletoYScale 使用浮点类型,1.0 表使原始大小,0.5 则是缩放一半,1.5 则是扩大原大小的一半。举例:原 View 宽高 100、150,1.0:(100,150),0.5:(50,75),1.5:(150,225)。也可以使用精确值(DP/PX)。

pivotXpivotY有三种表使方法,第一是采用像素值,第二则是较自身的百分比,第三则是较父 View 的百分比。

为了方便观察,使用两个同等位置和大小不同颜色的 View 来进行观察。动画的播放代码在最下文已给出。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <Button android:layout_width="match_parent" android:layout_height="wrap_content"
            android:text="播放动画"
            android:id="@+id/btnOpenAnimation"
    />
    <TextView android:layout_width="300dp" android:layout_height="300dp"
              android:layout_centerInParent="true"
              android:layout_gravity="center"
              android:background="#03A9F4"/>
    <TextView android:layout_width="300dp" android:layout_height="300dp"
              android:layout_centerInParent="true"
              android:id="@+id/txtAnimation"
              android:layout_gravity="center"
              android:background="#FF00"/>
</RelativeLayout>

示例 1:使用像素值确定 Pivot 点

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromXScale="0.5"
       android:toXScale="1.0"
       android:duration="3000"
       android:fromYScale="0.5"
       android:toYScale="1.0"
       android:pivotX="200"
       android:pivotY="200">
</scale>

这里我们分别设置了 pivotXpivotY为 200(px),这个是从 View 本身来算起的,View 的左上角为 (0,0) 点,然后 X 轴坐标向右,Y 则向下分别走 200 像素,最终得到了箭头指向的点(Pivot),那么开始点确定了。

再看其它参数,fromXScale指定的是在动画开始时 X 坐标也就是宽度的大小 (这里是按照比例计算的),0.5 则代表 View 原始宽度的一半,fromYScale 则是高度了。

既然是向特定的比例进行缩放,仅仅确定开始的大小是不够的,还要确定在动画播放到最后所要达到的大小,所以就有了 toXScaletoYScale,这两个则是指定在动画播放完成后 View 所处的大小。

这里我们是从 View 的 0.5 缩放到 1.0,也就是从原始 View 的一半经过 3 秒 (duration 用来控制动画时长,1000 为 1 秒。)后变成原始 View 的大小也就是 1.0。

示例 2:百分比 Pivot

使用百分比确定 Pivot 也很简单,那么 Pivot 的位置就是:以 View 的左上角即 (0,0) 点为基础加上 View 特定的宽高百分比。

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromXScale="0.0"
       android:toXScale="1.0"
       android:duration="5000"
       android:fromYScale="0.0"
       android:toYScale="1.0"
       android:pivotX="70%"
       android:pivotY="70%">
</scale>

示例 3:父 View 百分比 Pivot

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromXScale="0.0"
       android:toXScale="1.0"
       android:duration="5000"
       android:fromYScale="0.0"
       android:toYScale="1.0"
       android:pivotX="50%p"
       android:pivotY="50%p">
</scale>

这个计算和上边那个其实是一样的,只是基于的点不同而已,上边是基于自身来算起,那么这个则是基于 View 的父布局来计算的。那么 Pivot 的位置就是: 以 View 的左上角即 (0,0) 点为基础加上父 View 特定的宽高百分比。

alpha 动画

这个可以说就非常简单了,主要是实现颜色的过度效果,fromAlpha则是动画开始的透明度,toAlpha则是在动画最后显示的透明度。0.0 代表完全透明 1.0 则是 View 的原色。

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromAlpha="0.0"
       android:duration="3000"
       android:toAlpha="1.0">
</alpha>

rotate(旋转) 动画

首先要想完成旋转要确定那些参数?肯定要确定旋转要围绕的点也就是 pivot,这个在scale 动画也用到了,用法都一样,不在多说。这里出现了名为 degrees 也就是角度的概念,也就是以特定点 (pivot) 为中心从多少度(fromDegrees),旋转到多少度(toDegrees)。以下示例是从 0 转到 360 度,正好一圈。

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotY="50%"
        android:pivotX="50%"
        android:duration="3000"
>
</rotate>

translate(位移) 动画

说白了就是移动 View 的位置,就是从一个点移动到另一个点,最重要的就是确定两个点,那么则需要确定两对 X,Y 坐标了。

以下参数的使用方式和在最上边提到的 pivot 是一样的都可以使用精确值和百分比。

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:fromXDelta="10%"
           android:toXDelta="70%"
           android:fromYDelta="0%"
           android:toYDelta="70%"
           android:duration="3000">
</translate>

其中黑色线条框住的是 View 的原始位置,黄色框住的是 View 动画开始时的位置,紫色线条则是整个 View 的 70% 的占比,最后集中到的点就是 View 要移动到的最终的位置也就是结束点。

Set(集合动画)

如何理解 Set(集合动画),其实很简单,比如现在有一个需求,我们既要旋转又要有渐渐出现的效果,那么就要使用set 了,说白了就是将多个动画组合起来。只要把上边几个都学会了,使用这个 set 简直 so easy。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:duration="3000">
    <alpha
            android:fromAlpha="0.0"
            android:toAlpha="1.0"
    ></alpha>
    <rotate
            android:pivotX="50%"
            android:pivotY="50%"
            android:fromDegrees="0"
            android:toDegrees="180"
    ></rotate>
</set>

动态创建动画

上边所展示的都是通过 xml 文件写的动画,都是静态写好了的。那么想要动态的创建动画对象又该如何?其实很简单,通过代码的方式创建动画它们的名称和使用 xml 文件创建时名称都是对应的,提供的构造函数也都是必备的参数值。

 // 创建 Alpha 动画
var alpha = AlphaAnimation(0.0F, 1.0F)
alpha.duration = 3000
this.txtAnimation.startAnimation(alpha)
// 创建 Rotate 动画
var rotate = RotateAnimation(0F, 360F, Animation.RELATIVE_TO_SELF, 50F, Animation.RELATIVE_TO_SELF, 50F)
// 创建 Scale 动画
var scale = ScaleAnimation(0F, 1F, 0F, 1F, Animation.RELATIVE_TO_SELF, 50F, Animation.RELATIVE_TO_SELF, 50F)
// 创建 translate 动画
var translate = TranslateAnimation(
    Animation.RELATIVE_TO_SELF,
    10F,
    Animation.RELATIVE_TO_SELF,
    80F,
    Animation.RELATIVE_TO_SELF,
    0F,
    Animation.RELATIVE_TO_SELF,
    70F
)
// 创建 Set 动画
var set = AnimationSet(this, null)
set.duration = 3000
set.addAnimation(alpha)
set.addAnimation(rotate)

从 Animation 继承的属性

以上所有的动画对象都是从 Animation 类继承来的,所有有一些公共的属性也会继承过来。

动画的播放

// 加载动画
this.btnOpenAnimation.setOnClickListener {var animation = AnimationUtils.loadAnimation(this, R.anim.translate_anim)
    this.txtAnimation.startAnimation(animation)
}

Tween Animation(逐帧动画)

这个是 Drawable 形式的动画,存放在 drawable 文件夹中,使用 animation-list 节点来表示。图片素材是提前准备好的。自己动手尝试下马上就会理解了。

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:duration="100" android:drawable="@drawable/a001"></item>
    <item android:duration="100" android:drawable="@drawable/a002"></item>
    <item android:duration="100" android:drawable="@drawable/a003"></item>
    <item android:duration="100" android:drawable="@drawable/a004"></item>
    <item android:duration="100" android:drawable="@drawable/a005"></item>
    <item android:duration="100" android:drawable="@drawable/a006"></item>
    <item android:duration="100" android:drawable="@drawable/a007"></item>
    <item android:duration="100" android:drawable="@drawable/a008"></item>
    <item android:duration="100" android:drawable="@drawable/a009"></item>
    <item android:duration="100" android:drawable="@drawable/a010"></item>
    <item android:duration="100" android:drawable="@drawable/a011"></item>
    <item android:duration="100" android:drawable="@drawable/a012"></item>
    <item android:duration="100" android:drawable="@drawable/a013"></item>
    <item android:duration="100" android:drawable="@drawable/a014"></item>
    <item android:duration="100" android:drawable="@drawable/a015"></item>
    <item android:duration="100" android:drawable="@drawable/a016"></item>
    <item android:duration="100" android:drawable="@drawable/a017"></item>
    <item android:duration="100" android:drawable="@drawable/a018"></item>
</animation-list>

这里我们给一个 TextView 设置了 background 属性。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    <Button android:layout_width="match_parent" android:layout_height="wrap_content"
            android:text="播放动画"
            android:id="@+id/btnOpenAnimation"
    />
    <TextView android:layout_width="300dp" android:layout_height="300dp"
              android:layout_centerInParent="true"
              android:id="@+id/txtAnimation"
              android:background="@drawable/anim_refresh"
              android:layout_gravity="center"
    />
</RelativeLayout>

具体调用

var animationDrawable = this.txtAnimation.background as AnimationDrawable
animationDrawable.start()

显示效果

退出移动版