Android 动画-View Animation

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

Android 动画-View Animation

Tween Animation

Tween Animation(补间动画)能够做一些简单的动画效果,比如平移、旋转、缩放、透明度、以及四种动画效果的组合。Android 关于Tween Animation在android.view.animation中。

补间动画有两种实现方式:

  • 通过XMLl配置文件创建动画
  • 通过JAVA对象创建动画

通过xml配置文件创建动画

可以通过两种方式进行创建补间动画,但是使用xml更简单些,谷歌官方也推荐使用这个方式,我们会把xml配置文件放到**/res/anim**

我们先来了解一些标签:

:创建动画的根目录

:平移动画

:缩放动画

:翻滚动画

: 透明度动画

比如,我们创建一个translate.xml,表示一个平移动画:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="true"  
     android:fillAfter="true"
     android:duration="3000"
     android:repeatMode="reverse"
     android:interpolator="@android:anim/cycle_interpolator">
  <!--属性
     shareInterpolator:表示集合中的动画是否和集合共享同一个插值器。如果集合不指定插值				器,那么子动画就需要单独制定所需的插值器或者使用默认值
     duration:动画持续时间
     fillAfater:动画结束以后View是否停留在结束位置,true表示View停留在结束位置,false				则不停留
      android:repeatMode  动画重复的Mode
     -->
    <translate
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="500"
            android:toYDelta="500"
        />
   <!-- 平移动画
    android:fromXDelta-表示x的起始值
    android:toXDelta-表示x的结束值
    android:fromYDelta-表示y的起始值
    android:toYDelta-表示y的结束值
    -->
</set>

当需要组合动画的时候uni_animation.xml,我们可以这样写:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="true"
    android:duration="300"
    android:fillAfter="true"
 		android:repeatCount="infinite"
    android:repeatMode="reverse"
    >
    <!--属性
     shareInterpolator:表示集合中的动画是否和集合共享同一个插值器。如果集合不指定插值器,那么子动画就需要单独制定所需的插值器或者使用默认值
     duration:动画持续时间
     fillAfater:动画结束以后View是否停留在结束位置,true表示View停留在结束位置,false则不停留
      android:repeatMode  动画重复的Mode
			repeatCount:重复动画次数 当值为infinite时无限循坏
     -->

    <alpha
        android:fromAlpha="0.1"
        android:toAlpha="1"></alpha>
    <!--透明度动画
     fromAlpha表示透明度起始值,
     toAlpha表示透明度结束值-->


    <scale
        android:fromXScale="0.5"
        android:fromYScale="0.5"
        android:pivotX="20"
        android:pivotY="20"
        android:toXScale="1.2"
        android:toYScale="1"
        ></scale>
    <!--缩放动画
    android:fromXScale-水平方向缩放的起始值
    android:toXScale-水平方向缩放结束值
    android:fromYScale-竖直方向缩放的起始值
    android:toScale-竖直方向缩放结束值
    android:pivotX 缩放轴点的x坐标
    android:pivotY缩放轴点的y坐标-->

    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="100"
        android:toYDelta="100"></translate>
    <!-- 平移动画
    android:fromXDelta-表示x的起始值
    android:toXDelta-表示x的结束值
    android:fromYDelta-表示y的起始值
    android:toYDelta-表示y的结束值
    -->

    <rotate
        android:fromDegrees="0"
        android:pivotX="10"
        android:pivotY="10"
        android:toDegrees="180"></rotate>
    <!--旋转动画
    android:fromXDelta-旋转开始的角度
    android:toDegrees="180"-旋转结束的角度
    pivotX 缩放轴点的x坐标
    pivotY缩放轴点的y坐标
     默认情况下轴点是View的中心点-->  
</set>

配置好xml文件后,我们可以通过AnimationUtils 加载xml文件生成特定的Animation.

lateinit var mUniAnimation: Animation
mUniAnimation = AnimationUtils.loadAnimation(this, R.anim.uni_animation)
view.startAnimation(mUniAnimation)

配置文件创建补间动画,是简单里面最常用的方式,代码也简单。

通过Java对象创建动画

Android Library为补间动画提供了一些API:

  • TranslateAnimation 平移动画
  • ScaleAnimation 缩放动画
  • AlphaAnimation 透明度渐变动画
  • RotateAnimation 翻转动画
  • AnimationSet 动画集

以AnimationSet为列子,我们创建一个平移、缩放、透明度、翻转的动画。

				lateinit var mUniAnimation: AnimationSet
				
				//各类动画
				lateinit var mTranslateAnimation: Animation
    		lateinit var mScaleAnimation: Animation
    		lateinit var mAlphaAnimation: Animation
   			lateinit var mRotateAnimation: Animation
				//创建需要添加到AnimationSet的动画
        mTranslateAnimation = TranslateAnimation(0f,500f,0f,500f)
        mScaleAnimation = ScaleAnimation(0.5f,5f,0.5f,5f)
        mAlphaAnimation = AlphaAnimation(0.1f,1f)
        mRotateAnimation = RotateAnimation(0f,180f)

        mUniAnimation = AnimationSet(true)
        //动画间隔
        mUniAnimation.duration=3000
        //插值d
        mUniAnimation.interpolator=AccelerateInterpolator()
        //重复模式
        mUniAnimation.repeatMode=Animation.REVERSE
        //重复次数
        mUniAnimation.repeatCount=5
        //添加组合动画
        mUniAnimation.addAnimation(mTranslateAnimation)
        mUniAnimation.addAnimation(mScaleAnimation)
        mUniAnimation.addAnimation(mRotateAnimation)
        mUniAnimation.addAnimation(mAlphaAnimation)

创建后动画后,启动动画类似xml的方式:

iv_image.startAnimation(mUniAnimation)

Tween Animation 的监听事件

动画API提供了AnimationListener监听动画的状态:

  • 开启动画
  • 结束动画
  • 动画重复
mTranslateAnimation.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationRepeat(animation: Animation?) {
                // 当动画重复的时候触发
                Log.d("test","onAnimationRepeat")
            }

            override fun onAnimationStart(animation: Animation?) {
                // 当动画开始的时候触发
                Log.d("test","onAnimationStart")
            }

            override fun onAnimationEnd(animation: Animation?) {
                // 当动画结束的时候触发
                Log.d("test","onAnimationEnd")
            }

})

重复模式解析

动画框架有两个repeatMode:

  • Animation.RESTART 重复动画时从开始的状态启动动画
  • Animation.REVERSE 重复动画时从结束的状态回滚动画

如果我们想要设置无限动画,可以这样做:

        mTranslateAnimation.repeatCount=Animation.INFINITE
        mTranslateAnimation.repeatMode=Animation.REVERSE

Tween Animation 属性小结

名称 标签 子类 效果
平移动画 translate TranslateAnimation 移动View
缩放动画 scale ScaleAnimation 放大和缩小View
旋转动画 rotate RotateAnimation 旋转View
透明度渐变动画 alpha AlphaAnimation 改变View透明度

插值器小结

在定义动画的时候,一般我们只定义首帧和尾帧,然后由系统生成中间的帧数,生成中间帧的过程我们称为"插值",插值器就是定义动画变化速录过程。

下面是常见的插值器:

Interpolator对象 资源ID 功能作用
AccelerateDecelerateInterpolator @android:anim/accelerate_ decelerate_interpolator 先加速再减速
AccelerateInterpolator @android:anim/accelerate_ interpolator 加速
AnticipateInterpolator @android:anim/anticipate_ interpolator 先回退一小步然后加速前进
AnticipateOvershootInterpolator @android:anim/anticipate_ overshoot_interpolator 在上一个基础上超出终点一小步再回到终点
BounceInterpolator @android:anim/bounce_ interpolator 最后阶段弹球效果
CycleInterpolator @android:anim/cycle_interpolator 周期运动
DecelerateInterpolator @android:anim/decelerate_ interpolator 减速
LinearInterpolator @android:anim/linear_interpolator 匀速
OvershootInterpolator @android:anim/overshoot_ interpolator 快速到达终点并超出一小步最后回到终点

Frame Animation

逐帧动画:把静态图排序一张张展示成一帧帧的动画效果的动画叫逐帧动画

应用场景:主要应用于一些比较复杂的动画特效

注意点:因为逐帧动画是通过静态图一张张展示,所以在我们使用逐帧动画时,千万要注意不要把内存太大的静态图放在播放的动画中,否则会导致OOM

使用Xml创建Frame Animation

使用XML创建Frame Animation 一种很简洁的方式,创建Frame Animation的步骤如下:

  • 创建逐帧动画的xml文件并配置
  • 创建ImageView视图放置FrameAnimation xml 作为背景
  • 从ImageView中取出背景对象,转为AnimationDrawable
  • 使用AnimationDrawable对象API控制开始动画和结束动画

创建逐帧动画的xml文件并配置:

逐帧动画的资源放在res/drawable中:

根节点为animation-list,根节点animation-list有属性oneshot控制是否循环播放动画,当oneshot为true时仅播放一次,当oneshot为false时无限播放。

根节点animation-list有子节点item,有两个属性分别为duration代表每张图片的播放时间 ,drawable代表帧的静态图片资源索引。

代码示例如下:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
                android:oneshot="false" >

    <!-- animation-list 帧动画 -->
    <!-- android:oneshot的值为 false代表播放多次,true代表只播放一次 -->
    <!-- duration代表每张图片的播放时间 ,定义一个持续时间为50毫秒的动画帧 -->
    <item
            android:drawable="@drawable/img0"
            android:duration="50"/>
    <item
            android:drawable="@drawable/img1"
            android:duration="50"/>
    <item
            android:drawable="@drawable/img2"
            android:duration="50"/>
    <item
            android:drawable="@drawable/img3"
            android:duration="50"/>
   .....

</animation-list>

创建ImageView视图放置FrameAnimation xml 作为背景:

Frame Animation 在Android API 中的对象是AnimationDrawable是Drawable的子类,我可以设置成ImageViewd的背景图。

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".FrameAnimationJavaActivity">

        <Button
                android:id="@+id/btn_start"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="开启动画"/>

        <ImageView
                android:id="@+id/iv_image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/animationlist"/>
</LinearLayout>

从ImageView中取出背景对象,转为AnimationDrawable:

lateinit var mAnimationDrawable: AnimationDrawable

iv_image.setBackgroundResource(R.drawable.animationlist)
mAnimationDrawable=iv_image.background as AnimationDrawable

使用AnimationDrawable对象API控制开始动画和结束动画:

AnimationDrawableAPI 有三个比较重要的方法**AnimationDrawable.start()**开启动画、

**AnimationDrawable.stop()**停止动画、**AnimationDrawable.setOneShot(boolean)**设置是否无限循环。

    lateinit var mAnimationDrawable: AnimationDrawable
    var isStart=false
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_frame_animation_java)

        iv_image.setBackgroundResource(R.drawable.animationlist)
        mAnimationDrawable=iv_image.background as AnimationDrawable

        btn_start.setOnClickListener {
            if (isStart){
                isStart=false
                btn_start.text= "开启动画"
                mAnimationDrawable.stop()
            }else{
                isStart=true
                btn_start.text= "停止动画"
                mAnimationDrawable.start()
            }
        }


    }

使用Java创建Frame Animation

尽管平时我们更常用XML创建Frame Animation的方式,但是为了更好的理解Frame Animation,我还是想要讲一下在Android中,是如何通过Java代码创建Frame Animation的:

  • 创建AnimationDrawable对象
  • 动态装配静态图片
  • ImageView设置背景图
  • 控制是否开启停止动画

创建AnimationDrawable对象:

AnimationDrawable是Android 定义Frame Animation 的对象,可以通过创建AnimationDrawable来创建Frame Animation.

    lateinit var mAnimationDrawable: AnimationDrawable
		mAnimationDrawable=AnimationDrawable()

动态装配静态图片:

        var index=0
        while (index<25){
            //根据字符串名称 固定defType获取到资源Id
            val 		        id=resources.getIdentifier("img${index}","drawable",packageName)
            mAnimationDrawable.addFrame(resources.getDrawable(id),50)
            index++
        }

命名的时候,一般都是以图片唯一标示名+序列号来命名图片,把图片放在res/drawable里面,

通过**Resources.getIdentifier(“img${index}”:图片名,“drawable”:资源类型,packageName:包名)可以获取到资源唯一识别码ID,获取到资源ID后,使用Resources.getDrawable(ID)**获取到Drawable,逐帧添加到mAnimationDrawable中。

ImageView设置背景图:

 				//设置仅仅播放一次
        mAnimationDrawable.isOneShot=true
        // 设置背景图
        if (Build.VERSION.SDK_INT<=Build.VERSION_CODES.JELLY_BEAN){
            iv_image.setBackgroundDrawable(mAnimationDrawable)
        }else{
            iv_image.background=mAnimationDrawable
        }

控制是否开启停止动画:

控制动画开启还是停止,类似xml中的代码,这里我列出列子中的所有代码:

    var isStart=false
    lateinit var mAnimationDrawable: AnimationDrawable

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_frame_animation_java)

        mAnimationDrawable=AnimationDrawable()
        var index=0
        while (index<25){
            //根据字符串名称 固定defType获取到资源Id
            val id=resources.getIdentifier("img${index}","drawable",packageName)
            mAnimationDrawable.addFrame(resources.getDrawable(id),50)
            index++
        }
        //设置仅仅播放一次
        mAnimationDrawable.isOneShot=true
        // 设置背景图
        if (Build.VERSION.SDK_INT<=Build.VERSION_CODES.JELLY_BEAN){
            iv_image.setBackgroundDrawable(mAnimationDrawable)
        }else{
            iv_image.background=mAnimationDrawable
        }

        btn_start.setOnClickListener {
            if (isStart){
                isStart=false
                btn_start.text= "开启动画"
                mAnimationDrawable.stop()
            }else{
                isStart=true
                btn_start.text= "停止动画"
                mAnimationDrawable.start()
            }
        }
    }

AnimatedVectorDrawable

以下为参考资料:

Android动画之View Animation

Android动画之逐帧动画(FrameAnimation)详解

[Android动画效果之Frame Animation(逐帧动画)](

猜你喜欢

转载自blog.csdn.net/u010782846/article/details/94735150