android动画入门,Android动画基础总结
Android动画主要分为两种,视图动画和属性动画,视图动画又分为补间动画和帧动画两种。补间动画包含透明动画(Alpha),缩放动画(Scale),平移动画(Translate),旋转动画(Rotate);帧动画是切换图片的动画;属性动画通过改变属性令视图达到动画效果。
目录
1. 视图动画
补间动画
帧动画
2. 属性动画
值动画
对象动画
3. 总结
1. 视图动画
1.1 补间动画
补间动画包含透明动画(Alpha),缩放动画(Scale),平移动画(Translate),旋转动画(Rotate),可以在控件上通过startAnimation方法启动动画,传入一个Animation类作为参数,这个类是AlphaAnimation,ScaleAnimation,TranslateAnimation,RotateAnimation的基类,通过AnimationUtils.loadAnimation方法进行创建。下面来一一解析。
透明动画(Alpha)
透明动画是一个改变视图透明度的动画。下面来创建一个透明动画:
在res/anim里新建一个xml文件 anim_alpha
android:duration="2000"
android:fromAlpha="0.1"
android:toAlpha="1" />
其中的属性duration表示动画持续时间,fromAlpha表示透明度起始值,toAlpha表示透明度的终止值。
在布局文件里放一个TextView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello world"
android:textColor="#000"
android:textSize="48dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
通过AnimationUtils.loadAnimation方法创建一个Animation,传入两个参数,第一个是页面的Context,第二个是anim文件
var animation: Animation = AnimationUtils.loadAnimation(this, R.anim.anim_alpha)
通过startAnimation方法启动动画
textView.startAnimation(animation)
运行代码,textView在2秒内从透明度为0.1渐变到1。
缩放动画(Scale)
缩放动画是一个改变视图大小的动画。下面来创建一个缩放动画:
在res/anim里新建一个xml文件 anim_scale
android:duration="2000"
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="0.5"
android:toYScale="0.5" />
fromXScale表示宽度起始比例,fromYScale表示高度起始比例,toXScale表示宽度终止比例,toYScale表示高度终止比例。通过startAnimation方法启动动画
var animation: Animation = AnimationUtils.loadAnimation(this, R.anim.anim_scale)
textView.startAnimation(animation)
运行代码,textView的宽高在2秒内从原来的大小缩小到一半。
平移动画(Translate)
平移动画是一个改变视图位置的动画。下面来创建一个平移动画:
在res/anim里新建一个xml文件 anim_translate
android:duration="2000"
android:fromXDelta="50"
android:fromYDelta="50"
android:toXDelta="200"
android:toYDelta="200" />
fromXDelta表示X轴起始位置,fromYDelta表示Y轴起始位置,toXDelta表示X轴终止位置,toYDelta表示Y轴终止位置。通过startAnimation方法启动动画
var animation: Animation = AnimationUtils.loadAnimation(this, R.anim.anim_translate)
textView.startAnimation(animation)
运行代码,textView在2秒内从x=50,y=50的位置移动到x=200,y=200的位置。
旋转动画(Rotate)
旋转动画是一个视图根据围绕中心点旋转的动画。下面来创建一个旋转动画:
在res/anim里新建一个xml文件 anim_rotate
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="361" />
fromDegrees表示起始角度,toDegrees表示顺时针旋转角度(值为负数时逆时针旋转),pivotX表示中心点X轴坐标,pivotY表示中心点Y轴坐标,如上面 pivotX=“50%”,pivotY="50% 指的是控件的中心位置。通过startAnimation方法启动动画
var animation: Animation = AnimationUtils.loadAnimation(this, R.anim.anim_rotate)
textView.startAnimation(animation)
运行代码,textView围绕自己的中心顺时针旋转361°。
组合动画
上面举了4种动画单个启动的例子,那么如果想把他们组合在一起,该怎么用呢。举个例子:
在res/anim里新建一个xml文件 anim_group,把上面4种动画都放进去
android:duration="2000">
android:fromXDelta="50"
android:fromYDelta="50"
android:toXDelta="200"
android:toYDelta="200" />
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="361" />
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="0.5"
android:toYScale="0.5" />
android:fromAlpha="0.1"
android:toAlpha="1" />
这样就得到一个组合动画,启动动画的方式也是一样
var animation: Animation = AnimationUtils.loadAnimation(this, R.anim.anim_group)
textView.startAnimation(animation)
运行代码,查看效果:
状态停留
上面举的例子都是动画播放完后视图回到原来的位置,如果视图想保持动画播放完后的状态,可以在xml文件的标签内添加属性fillAfter,true为状态停留在动画播放完后,也可以在代码中设置。如下所示:
android:duration="2000"
android:fillAfter="true">
···
//或者再代码中设置
animation.fillAfter = true
运行代码,查看效果:
循环播放
上面举的例子都是动画播放完就自动停止了,如果想要循环播放,可以监听动画播放,如下所示:
animation.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationRepeat(animation: Animation?) {
}
override fun onAnimationEnd(animation: Animation?) {
animation?.reset()
animation?.start()
}
override fun onAnimationStart(animation: Animation?) {
}
})
Animation.AnimationListener可以监听动画的开始、结束、重播。如果想循环播放动画,可以在动画结束时调用reset()重置动画,然后调用start()播放。如果想要停止播放,可以在视图上调用clearAnimation()清楚动画,如下所示:
textView.startAnimation(animation)
textView.setOnClickListener {
textView.clearAnimation()
}
运行代码,效果如下:
插值器(Interpolator)
Interpolator可以控制动画变化的速率,使动画效果能够以匀速、加速、减速等多种速率变化,默认是匀速(LinearInterpolator)。当我们需要设置Interpolator时,可以在xml文件的标签内添加属性fillAfter,true为状态停留在动画播放完后,也可以在代码中设置。如下所示:
android:interpolator="@android:anim/accelerate_interpolator">
...
//或者再代码中设置
animation.setInterpolator(AccelerateInterpolator())
//为了更好地观察效果,把持续时间改为4秒
animation.duration = 4000
AccelerateInterpolator是一个加速度插值器,动画播放起始速度变慢,但是速度越来越快,如下所示:
如果觉得效果不够明显,还可以给AccelerateInterpolator设置属性factor,factor是一个float类型的值,值越大起始速度越慢,但是速度越来越快,下面把factor设置成2f再来看一下效果:
animation.setInterpolator(AccelerateInterpolator(2f))
除了AccelerateInterpolator之外,还有很多不同的插值器,下面来一一列举:
插值器
说明LinearInterpolator
变化速率恒定(默认)
AccelerateInterpolator
开始速率较慢,后面加速
AccelerateDecelerateInterpolator
开始和结束速率较慢,中间加速
DecelerateInterpolator
开始速率较快,后面减速
AnticipateInterpolator
开始时向后飞溅,然后向前
AnticipateOvershootInterpolator
开始时向后飞溅,然后向前,结束前冲过目标值,又回到目标值
OvershootInterpolator
开始时向前飞溅,结束前冲过目标值,又回到目标值
BounceInterpolator
结束时反弹
CycleInterpolator
动画循环播放特定的次数,速率沿着正弦曲线改变
1.2 帧动画
帧动画是一种一帧一帧播放的动画。下面举个例子:
首先我准备了4张图
在res/drawable里新建一个根属性为animation-list的anim_frame.xml,把4张图片放进去,其中oneshot属性如果为true时,动画只播放一次,如果为false则循环播放
android:oneshot="false">
![![giftest13.gif](https://upload-images.jianshu.io/upload_images/2787721-b8bc65b2b25c5acd.gif?imageMogr2/auto-orient/strip)
](https://upload-images.jianshu.io/upload_images/2787721-0690977f6495c791.gif?imageMogr2/auto-orient/strip)
android:drawable="@drawable/pic01"
android:duration="100" />
android:drawable="@drawable/pic02"
android:duration="100" />
android:drawable="@drawable/pic03"
android:duration="100" />
android:drawable="@drawable/pic04"
android:duration="100" />
在布局文件中添加一个ImageView来播放帧动画
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
播放动画
//为ImageView设置资源
imageView.setImageResource(R.drawable.anim_frame)
//AnimationDrawable是用于创建逐帧动画的对象
var animationDrawable: AnimationDrawable
animationDrawable = imageView.drawable as AnimationDrawable
imageView.setOnClickListener {
//点击imageView启动动画
animationDrawable.start()
}
运行代码,查看结果
2. 属性动画
上面说到的补间动画,只提供了几种基础动画,可扩展性不强,而且在动画播放的过程中,只改变了视图的视觉效果,并没有改变他们的属性。为了弥补补间动画的缺点,在 Android 3.0 开始提供了属性动画。属性动画是通过改变对象属性实现的动画,分为值动画(ValueAnimator)和对象动画(ObjectAnimator)两种。
2.1 值动画(ValueAnimator)
值动画是通过控制对象属性的变化,不断赋值给对象的属性实现的动画。ValueAnimator有3个比较重要的方法:
ValueAnimator.ofInt(int values)
ValueAnimator.ofFloat(float values)
ValueAnimator.ofObject(int values)
以ofInt(int values)为例,介绍一下值动画实现方法:
1.创建值动画实例,调用ValueAnimator.ofInt(int values)设置值范围,当参数为一个时,传入的参数为结束值;当参数为两个时,第一个参数为起始值,第二个参数为结束值。
2.设置动画播放的各种属性
setDuration(long duration)
设置播放时长
setStartDelay(long duration)
设置延迟播放时间
setRepeatCount(int value)
设置重复播放次数,value为0时不重播,value为ValueAnimator.INFINITE时无限重播
setRepeatMode(int value)
设置重播模式,value为ValueAnimator.RESTART(默认)时正序重放,value为ValueAnimator.REVERSE时倒序回放
3.调用addUpdateListener()监听动画播放,通过估值器(ValueAnimator.ofInt()方法默认估值器为IntEvaluator),每变化一次,估值器就会根据比例、起始值、结束值来计算具体变化数值,然后把新的值赋给对象的属性,再重新绘制。
4.开始动画
完整代码如下
val anim = ValueAnimator.ofInt(textView.layoutParams.width, 500)
anim.setDuration(3000)//播放时间为3秒
anim.setStartDelay(0)//不延迟播放
anim.setRepeatCount(0);//不重播
anim.repeatMode = ValueAnimator.RESTART//正序重播
anim.addUpdateListener {
var value = it.getAnimatedValue() as Int//获取变化后的值
textView.layoutParams.width = value//新的值赋给对象的属性
textView.requestLayout()//重新绘制
}
textView.setOnClickListener { anim.start() }
点击textView动画开始,textView会在3秒内从原来的宽度拉长到目标值500,效果如下:
ofFloat()与ofInt()大同小异,ofInt()将起始值以整形数值的形式过渡到结束值,而ofFloat()将起始值以浮点型数值的形式过渡到结束值。ofFloat()的默认估值器为FloatEvaluator。ofObject()与前两个方法不同的是,它以对象的形式将起始值过度到结束值,没有默认的估值器,只能通过自定义估值器来实现。
2.2 对象动画(ObjectAnimator)
ValueAnimator通过监听动画播放,不断获取并更新对象的属性值,实现动画效果,算是一个“手动”赋值的方式,而ObjectAnimator则是一种“自动”的方式。ObjectAnimator继承ValueAnimator,所以在用法上他们差别不大,下面举个例子:
用ObjectAnimator实现像补间动画的缩放动画那样的效果,代码如下:
val animator = ObjectAnimator.ofFloat(textView, "scaleX", 1f, 2f)
animator.setDuration(3000)
animator.start()
首先创建ObjectAnimator实例,调用ofFloat()方法并传入对应的参数,第一个参数为展示动画的对象,第二个参数为需要改变的属性,这个参数可以传入任意属性名,ObjectAnimator根据该属性名找到该对象属性的get() & set()方法进行“自动”赋值,如上面传入"scaleX",ObjectAnimator会调用scaleX的get() & set()方法对其属性进行赋值,所以如果需要采用ObjectAnimator类实现动画效果,那么需要操作的对象就必须有该属性的get() & set()方法。后面的参数为起始结束值,如果属性没有提供起始值,则调用属性的get()方法取值。因为ObjectAnimator继承ValueAnimator,所以可以跟ValueAnimator一样设置动画播放的各种属性。运行代码:
textView在3秒内从自身宽度拉长到两倍。
同样的如果要自定义对象动画,只需仿照上面例子,定义好需要操作的属性,并提供该属性的get() & set()方法。关于如何自定义对象动画,本篇就不再详解了。
3. 总结
本篇文章主要介绍了Android动画分为视图动画和属性动画两种,视图动画又分为补间动画和帧动画。帧动画主要是以一帧一帧地播放图片来展示动画;补间动画主要以透明度、缩放、选择、平移等改变视图的显示方式来展示动画;属性动画分为以“手动”或“自动”改变对象的属性值的方式来展示动画。Android动画能让app与用户交互的时候变得更有趣,而实际上在开发中也是经常会运用到动画知识,所以学好Android动画也是每一个Android开发者的必修课。本篇文章内容浅显,只说到了动画的基础知识,后面会由浅入深继续介绍Android动画,有兴趣的可以继续关注。
android动画入门,Android动画基础总结相关推荐
- android动画入门,Android动画之入门篇(一)
作为Android开发者,动画是非常重要的知识点,本文主要从入门角度来探索动画. Android的动画主要包括三大类:逐帧(Frame)动画,补间(Tween)动画,属性动画. 1. 逐帧(Frame ...
- android地图入门,android 百度地图入门01 (史上最详没有之一)
最近一直和百度地图打交道,写几篇博客记录一下吧,目前最新版是4.0的 ,之前我用的是3.7的, 就以4.0的为例说一下最基本的配置流程吧. 一.准备工作 1.申请一个百度地图开发者账户--地址:htt ...
- android camera入门,android 基础一 Camera1 预览、拍照
预览流程: Camera.open-->camera.setPreviewDisplay->camera.startPreview 拍照:camera.takePicture-->保 ...
- android retrofit入门,Android开发 retrofit入门讲解
前言 retrofit基于okhttp封装的网络请求框架,网络请求的工作本质上是 OkHttp 完成,而 retrofit 仅负责网络请求接口的封装.如果你不了解OKhttp建议你还是先了解它在来学习 ...
- android开发入门_Android开发入门
android开发入门 Android is an open source, Linux-based mobile operating system. Android was developed by ...
- android mqtt详解_Android mqtt入门 Android studio(转)
Android mqtt入门 Android studio 2018年04月09日 14:02:30 hbw020 阅读数:1564 分享 mqtt简单使用介绍: 1.as创建工程 2.官网下载mqt ...
- Android自定义控件开发入门与实战(7)SVG动画,android底层架构
move to (50,23) line to(100,25) 而坐标并不是用width和height的坐标,而是viewportWidth和viewportHeight的坐标,(50,23)中50表 ...
- Android控件入门-动画效果(透明度动画)
透明度动画(alpha): 第一种方式: xml: <Buttonandroid:id="@+id/btn_alpha"android:layout_width=" ...
- android实现加载等待动画,【Android 基础】Progressbar 实现Loading动画
image.png Progressbar 实现Loading动画 网络加载,播放视频 loading 时候界面会显示 转圈 等待提示动画,使用Android 自带的Progressbar 即可实现, ...
最新文章
- 2022-2028年中国可生物降解农用薄膜产业竞争现状及投资决策建议报告
- 201521123016《Java程序设计》第12周学习总结
- 手机号码 与 邮箱验证
- React | Expected an assignment or function call and instead saw.....
- [《孔雀》观后]聪明的孩子提着易碎的灯笼
- 学习spring过程看的笔记(一)
- 对象关系映射(ORM)及代码生成器和插件C#源码(DBFrameworkV4.5.3)
- 使用GPUImage实现视频滤镜
- Java对象运行时在内存中的情况
- SMSSDK接入(Mob短信SDK接入)
- [培训-DSP快速入门-1]:DSP概述(基本框架、CPU, GPU, FPGA比较,常见型号)
- 《大众创业做电商——淘宝与微店 开店 运营 推广 一册通》一一1.2 创业者应具备的条件与经验...
- 瞬态电压抑制二极管选型指导,一场走心的科普之旅
- Python调用kafka构建完整实例分析与应用!
- 为什么iPhone 12 中国版不支持5G毫米波?
- 查询出编号长度大于4的code_中国大学MOOC-翁恺-C语言程序设计习题集-解答汇总...
- 魅蓝note2解锁bootloader教程
- 宠物经济:吃、用、病、葬都是生意
- 动手深度学习笔记(一)2.1数据操作
- svn: OPTIONS of 'https://lym-pc/svn/CRM': Could not resolve hostname 'lym-pc'
热门文章
- 魅族适配android9.0,魅族安卓7.0适配进度公布:9款机型正在适配,但BUG有点多
- [转]PHP开发框架的现状和展望
- kingroot权限管理_KingRoot(授权管理)
- Qt入门之Widget Application
- 在百度开放云平台上构建Web App
- Snapgene打不开序列,序列无法显示怎么办?5.0不能正常使用?
- 用飞桨扛起日本分类竞赛头旗!绽放你的能量!—— 训练篇(一)
- Codeforces Round #636 (Div. 3)部分题解
- 在Eclipse中引用Jquery框架路径问题
- 如何学习使用 Axure?