Android 动画-View Animation
作者:互联网
Android 动画-View Animation
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动画之逐帧动画(FrameAnimation)详解
[Android动画效果之Frame Animation(逐帧动画)](
标签:xml,动画,AnimationDrawable,创建,Frame,Animation,Android,View 来源: https://blog.csdn.net/u010782846/article/details/94735150