[0 to 0.5]从零开始学习Android动画知识(上)

为什么要学习动画

当然是因为COOL啊

用户对产品的体验是由多种要素构成的。

在APP开发过程中,影响产品最终形象的元素有很多,而动画效果一直是其中不可或缺的一部分。

好的动画效果不仅可以在单一界面中容纳更多信息传达并反馈更多的状态 (更炫酷);
还可以引导用户对产品的交互,促进用户对信息的理解,使用产品时更加流畅 (更简单)。

动画框架

Android的动画本来有两种:补间动画(Tween Animation)和逐帧动画(Frame Animation),并统称为视图动画(View Animation),在Android3.0(API 11)之后又加入了属性动画 (Property Animation)。

#mermaid-svg-fGNwFpBC7U7hBc54 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fGNwFpBC7U7hBc54 .error-icon{fill:#552222;}#mermaid-svg-fGNwFpBC7U7hBc54 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fGNwFpBC7U7hBc54 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-fGNwFpBC7U7hBc54 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fGNwFpBC7U7hBc54 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fGNwFpBC7U7hBc54 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fGNwFpBC7U7hBc54 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fGNwFpBC7U7hBc54 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fGNwFpBC7U7hBc54 .marker.cross{stroke:#333333;}#mermaid-svg-fGNwFpBC7U7hBc54 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fGNwFpBC7U7hBc54 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fGNwFpBC7U7hBc54 .cluster-label text{fill:#333;}#mermaid-svg-fGNwFpBC7U7hBc54 .cluster-label span{color:#333;}#mermaid-svg-fGNwFpBC7U7hBc54 .label text,#mermaid-svg-fGNwFpBC7U7hBc54 span{fill:#333;color:#333;}#mermaid-svg-fGNwFpBC7U7hBc54 .node rect,#mermaid-svg-fGNwFpBC7U7hBc54 .node circle,#mermaid-svg-fGNwFpBC7U7hBc54 .node ellipse,#mermaid-svg-fGNwFpBC7U7hBc54 .node polygon,#mermaid-svg-fGNwFpBC7U7hBc54 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fGNwFpBC7U7hBc54 .node .label{text-align:center;}#mermaid-svg-fGNwFpBC7U7hBc54 .node.clickable{cursor:pointer;}#mermaid-svg-fGNwFpBC7U7hBc54 .arrowheadPath{fill:#333333;}#mermaid-svg-fGNwFpBC7U7hBc54 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fGNwFpBC7U7hBc54 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fGNwFpBC7U7hBc54 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-fGNwFpBC7U7hBc54 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-fGNwFpBC7U7hBc54 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fGNwFpBC7U7hBc54 .cluster text{fill:#333;}#mermaid-svg-fGNwFpBC7U7hBc54 .cluster span{color:#333;}#mermaid-svg-fGNwFpBC7U7hBc54 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fGNwFpBC7U7hBc54 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

Animation
View Animation
Property Animation
Frame Animation
Tween Animation

视图动画(View Animation)

逐帧动画(Frame Animation)

简单来说,逐帧动画就是将一组预先准备好的图片通过控制依次显示并循环播放(参考幻灯片),从而造成一种动画效果。

通常逐帧动画有两种实现方式: XML 和 Java 。

用XML方法实现

首先,创建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/type1" android:duration="150" />
<item android:drawable="@drawable/type2" android:duration="150" /></animation-list>
  • android:oneshot 代表是否循环(true 为不循环,false 为循环)
  • drawable代表加入的图片素材,而duration代表该素材一帧的持续时长(ms)

然后,将上述XML文件(frame.xml)作为ImageView(image)的图像,并调用AnimationDrawable类获取该图像生成的实例

private ActivityMainBinding binding;
private AnimationDrawable frame;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());binding.image.setImageResource(getResources().getIdentifier("frame","drawable",getPackageName()));frame = (AnimationDrawable) binding.image.getDrawable();//获取实例binding.Start.setOnClickListener(view -> {frame.start();});binding.Stop.setOnClickListener(view -> {frame.stop();});
}

效果如下:

[查看图片]

用Java方法实现

Java代码实现逐帧动画和xml类似,相当于使用Java代码获取AnimationDrawable实例

private ActivityMainBinding binding;
private AnimationDrawable frame;
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);binding = ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());frame = new AnimationDrawable();for (int i = 1 ,id;i <= 2; i ++ ) {id = getResources().getIdentifier("type" + i, "drawable", getPackageName());frame.addFrame(getResources().getDrawable(id),150);}//相当于创建frame.xmlframe.setOneShot(false);//设置是否循环binding.image.setImageDrawable(frame);binding.Start.setOnClickListener(view -> {frame.start();});binding.Stop.setOnClickListener(view -> {frame.stop();});
}

逐帧动画的优缺点

优点:代码量小,使用较为方便、简单
缺点:动画的变化基于图片的切换,越是流畅的动画越需要更多的图片,从而占用了大量内存。所以,使用逐帧动画时一定要注意图片的大小和数目!

补间动画(Tween Animation)

补间动画是通过已确定的开始视图样式和结束视图样式,并由系统计算来补全其中间动画变化过程的动画

补间动画同样支持XML和Java两种方法,这里我推荐使用更易读、可切换、可重复使用的XML方法

Android支持的补间动画效果有以下4种:旋转(rotate)、位移(translate)、缩放(scale)和透明度(alpha)

动画名 对于Animation子类 res/anim/目录下xml标签 动画效果
缩放 ScaleAnimation <scale> 进行特定范围的缩放
透明度 AlphaAnimation <alpha> 改变透明度,实现隐现
位移 TranslateAnimation <translate> 进行位置的移动
旋转 RotateAnimation <rotate> 围绕特定的点进行旋转
复合 AnimationSet <set> 复合使用上述四种效果

上述动画的类均继承自Animation类,因此存在一些通用的动画属性和方法

xml属性 对应Java方法 效果
android:duration setDuration(long) 动画持续时间(ms)
android:fillAfter setFillAfter(boolean) 保持动画结束时的状态,默认ture
android:fillBefore setFillBefore(boolean) 还原到动画开始时的状态,默认为false
android:repeatCount setRepeatCount(int) 动画重复执行的次数
android:repeatMode setRepeatMode(int) 动画重复模式 ,restart从头开始,reverse倒叙回放
android:startOffset setStartOffset(long) 动画开始前延迟的时间(ms)
android:interpolator setInterpolator(Interpolator) 插值器,改变动画的不同阶段的执行速度

这里的插值器(interpolator)在属性动画中较为常用,我们将在后面细说。

透明度动画(Alpha)

xml方法代码

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"android:duration="2000"android:fromAlpha="1.0"android:toAlpha="0.0"/>
 animation = AnimationUtils.loadAnimation(this,R.anim.alpha_anim);

对应Java方法代码

animation = new AlphaAnimation(1,0);
animation.setDuration(4000);
binding.tween.startAnimation(animation);

这里的AlphaAnimation(float,float)的两个值域为 [0,1] 的参数分别对应

XML中的android:fromAlpha(初始透明度) 和 android:toAlpha(终止透明度)

且值越接近0,透明度越高

效果如下:

[查看图片]

旋转动画(Rotate)

xml方法代码

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

对应Java方法代码

animation = new RotateAnimation(0,180,Animation.RELATIVE_TO_SELF,0.50f,Animation.RELATIVE_TO_SELF,0.50f);
//RotateAnimation(fromDegrees,toDegrees,pivotXType,pivotX,pivotYType,pivotY)
animation.setDuration(1000);

显然,RotataAnimation()的前两个参数分别对应 android:fromDegrees(起始角度) 和 android:toDegrees(最终角度)

而这里多出来的两个常数参数 pivotXTypepivotYType分别指定了如何去解释pivotX和pivotY

Animation.ABSOLUTE Animation.RELATIVE_TO_SELF Animation.RELATIVE_TO_PARENT
指定尺寸是一个绝对像素数量。使用之后pivotX 或pivotY 的值都是绝对像素数量(px)。 指定尺寸是一个浮点数,用这个浮点数来乘动画对象的宽或高。如使用之后动画最终的x轴 =(pivotX 的值) * (动画对象的宽),即百分数 指定尺寸是一个浮点数,用这个浮点数来乘动画父对象的宽或高。如使用之后动画最终的x轴 =(pivotX 的值) * (动画父对象的宽),即百分数

效果如下:

[查看图片]

缩放动画(Scale)

xml方法代码

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

对应Java方法代码

animation = new ScaleAnimation(0,1,0,1,Animation.RELATIVE_TO_SELF,0.50f,Animation.RELATIVE_TO_SELF,0.50f);
//ScaleAnimation(fromXScale,toXScale,fromYScale,toYScale,pivotXType,pivotX,pivotYType,pivotY)
animation.setDuration(1000);

这里的fromXScaletoXScale分别确定了开始和结尾的缩放比例,而pivotX确定了缩放的中心

效果如下:

[查看图片]

位移动画(Translate)

xml方法代码

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

对应Java方法代码

animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0,1,0,1,0,1,1.30f);
//TranslateAnimation(fromXType,fromXDelta,toXType,toXDelta,fromYType,fromYDelta,toYType,toYDelta)
//这里为了控制代码长度,将Animation.RELATIVE_TO_SELF换成其对应值1
//还有一种常用的动画 TranslateAnimation(fromXDelta,toXDelta,fromYDelta,toYDelta)
//这时Delta代表的是坐标值
animation.setDuration(1000);

位移动画(Translate)的参数与旋转动画(Rotate)中的使用方法一致,不同的fromXType有不同的fromXDelta解释与之对应。

但要注意,Translate的百分数位置起始点是其左上角,即当fromDelta为0时,图像从左上角出发

效果如下:

[查看图片]

复合动画(Set)

顾名思义,Set动画即前几个动画的复合使用

xml方法代码

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/linear_interpolator"android:shareInterpolator="true"android:duration="2000"><alphaandroid:fromAlpha="0.5"android:toAlpha="1.0"/><scaleandroid:fromXScale="0.0"android:fromYScale="0.0"android:pivotX="50%"android:pivotY="50%"android:toXScale="1.0"android:toYScale="1.0"/><translateandroid:fromXDelta="0"android:fromYDelta="0"android:toXDelta="0%"android:toYDelta="100%"/><rotateandroid:fromDegrees="0"android:toDegrees="360"android:pivotY="50%"android:pivotX="50%"android:repeatCount="100"/>
</set>

对应Java方法代码

AnimationSet animationSet = new AnimationSet(true);
//AnimationSet(shareInterpolator)
animationSet.addAnimation(animation);
//只需将之前的其他动画的animation “加入” animationSet即可
binding.tween.startAnimation(animationSet);

AnimationSet(shareInterpolator)中的shareInterpolator是一个boolean类型的值

其为true时代表所有子动画共用一个Interpolator , linear_interpolator代表动画变化均匀

效果如下:

[查看图片]

Tween Animation的监听

动画监听器可以对动画的执行状态进行监听,并通过重写进行一系列操作

Animation.addListener(new AnimatorListener() {@Overridepublic void onAnimationStart(Animation animation) {//监听动画开始//对应animation.start()}@Overridepublic void onAnimationRepeat(Animation animation) {//监听动画重复}@Overridepublic void onAnimationCancel()(Animation animation) {//监听动画被取消//对应animation.cancel()}@Overridepublic void onAnimationEnd(Animation animation) {//监听动画执行结束}});

补间动画的优缺点

优点:使用简单,效果流畅,相比于逐帧动画来说不用准备大量素材

缺点:作用于视图对象View,未作用于属性。即所有View的移动、隐藏、旋转仅仅是看到的动画效果,实际View的位置/大小/比例并没有发生本质上的改变。

[0 to 0.5]从零开始学习Android动画知识(上)相关推荐

  1. [0 to 0.5]从零开始学习Android动画知识(下)

    [0 to 0.5]从零开始学习Android动画知识(下) 矢量动画(Scalable Vector Graphics) 不同于前面的为控件做动画效果的方法,矢量动画则是为图形做出动画效果 矢量图 ...

  2. [0 to 0.5]从零开始学习Android动画知识(中)

    [0 to 0.5]从零开始学习Android动画知识(中) 属性动画(Property Animation) 属性动画(Property Animation)是在 Android 3.0(API 1 ...

  3. 如何高效的学习Android动画

    前言 本篇文章就是在知乎回答的一个问题,这里记录下,以后看到我博客的朋友也可以看到. 曾经也同楼主一样,对Android中的动画不是很清楚,什么帧,Tween,属性等等,很多知识,也很琐碎,后来觉得动 ...

  4. 高效学习Android动画

    当时系统学习Android动画还有一部分原因:将来成为一个android组件开发工程师,如果想做出一些高性能,nice的动画就必须对动画的基础知识有深入的理解,因此就打算系统的学习一下.经过一段时间的 ...

  5. android编程从零开始,从零开始学习android开发

    博主最近开通了Android栏目,现在正在从零开始学习android,遇到的所有值得分享的知识点以及遇到的问题将发布在这个博客的android栏目下. 因为我有着深厚的java底子,所以学习起来得心应 ...

  6. 【Android -- 动画】如何学习 Android 动画?

    文章目录 Android Training & Guides 学习路线图 官方博客 GitHub 高星(感兴趣的)项目 Android Training & Guides Androi ...

  7. 动画学习android,Android动画学习

    个人觉得学习Android动画最好的方式就是看开发者文档,所以我就当做翻译,将文章翻译一次吧 Animation Resources 动画资源可以用来定义两种类型的动画 创建一种将图片上进行一系列变化 ...

  8. Android动画全解

    Android动画全解 在Android开发中经常会碰到动画,看到别的应用有很酷炫的应用时,总是想怎么去实现,但是每次都是发现感觉是知道怎么做的,实际做起来还是无从下手的感觉,究其原因还是 Andro ...

  9. 中国移动开发者社区专访:学习Android的两大法宝

    本文为原创,如需转载,请注明作者和出处,谢谢! 近日,接受了中国移动开发者社区的专访,谈了关于Android的一系列问题 http://dev.10086.cn/upload/developers_m ...

  10. 从零开始学android编程_小白也能学得会!谷歌推出免费的Kotlin和Android开发课程...

    程序员书库(ID:CodingBook) 猿妹编译 链接:https://android-developers.googleblog.com/2020/07/learn-android-and-kot ...

最新文章

  1. 支持异步同步的分布式CommandBus MSMQ实现 - 支持Session传递、多实例处理
  2. manjaro 宝塔面板_宝塔Linux面板FTP无法连接的解决办法
  3. WinPcap笔记(1):VisualStudio2015配置WinCap
  4. SQL Server2012如何导出sql脚本并且还原数据库
  5. 安装Linux后windows在哪启动,在Linux下安装windows后解决Linux不能启动能问题
  6. html5+css3第一次作业_“台风爷爷,让我作业飞走!”南京小学生写的诗都这么逆天了?...
  7. Covariance and Contravariance in C#, Part One
  8. sysadmin默认密码_从sysadmin过渡到DevOps工程师的案例
  9. python的文件夹_Python遍历文件夹和文件
  10. Promise的deferred对象详解
  11. 兼容各浏览器的js回车事件
  12. ubuntu java apt-get_ubuntu apt-get 安装jdk7
  13. CENTOS安装XXNET
  14. 中望cad文字显示问号怎么办_CAD文件打开后有很多问号怎么办
  15. 广告商业形态与应用架构
  16. pixi 流星_流星语270—273
  17. vue之设置背景图片自适应屏幕
  18. C++调用C# dll 未能加载文件或程序集
  19. STM32F1基于正点原子HAL库IIC驱动SH1106芯片的OLED屏
  20. Driver/library version mismatch

热门文章

  1. UE4像素流送PixelStreaming
  2. 微信公众号发送模板消息
  3. opencv3编程入门-毛星云
  4. 上海城建坐标与WGS84坐标转换工具
  5. PDF Explained(翻译)第一章 简介
  6. html表格之个人简历
  7. 在区块链的世界里,美国CFTC希望成为一个节点
  8. 智能优化算法——蝙蝠算法(PythonMatlab实现)
  9. BAD SYSTEM CONFIG INFO 修复办法
  10. java毕业设计水库洪水预报调度系统源码+lw文档+mybatis+系统+mysql数据库+调试