Android开发艺术探索学习笔记(七)

第七章 Android动画深入分析

Android的动画分为三种:View动画,帧动画,属性动画。帧动画属于View动画。

7.1 View动画

    View动画的作用对象是View,共有四种动画效果:平移(Translate),缩放(Scale),旋转(Rotate),透明度(Alpha)。

7.1.1 View动画的种类

 View动画的保存路径:res/anim/filename.xml。XML格式语法如下:

<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@anim/interpolator_resource"
android:shareInterpolator="true|false">
<alpha
android:fromAlpha="float"<!-- 透明度起始值-->
android:toAlpha="float"/><!-- 透明度结束值-->
<scale
android:fromXScale="float"<!--水平方向缩放起始值 -->
android:toXScale="float"<!--水平方向缩放结束值 -->
android:fromYScale="float"<!--垂直方向缩放起始值 -->
android:toYScale="float"<!--垂直方向缩放结束值 -->
android:pivotX="float"<!--缩放轴点x坐标 -->
android:pivotY="float"/><!--缩放轴点y坐标 -->
<translate
android:fromXDelta="float"<!--x的起始位置-->
android:fromYDelta="float"<!--y的起始位置-->
android:toXDelta="float"<!--x的结束位置-->
android:toYDelta="float"/><!--y的结束位置-->
<rotate
android:fromDegrees="float"<!--起始角度 -->
android:toDegrees="float"<!-- 结束角度-->
android:pivotX="float"<!-- 旋转轴点x坐标 -->
android:pivotY="float"/><!-- 旋转轴点y坐标-->
<set>
...
</set>
</set> 

<set>标签表示动画集合,对应AnimationSet类,内部还可以嵌套其他动画集合。

android:interpolator 插值器规定动画已怎样的速度运行,默认为加速减速插值器。

android:shareInterpolator 集合中的动画是否和集合共享同一个插值器。

android:duration 动画持续时间

android:fillAfter 动画结束后View是否停留在结束位置。

<scale>、<rotate>中轴点默认情况下是View的中心点(有待验证貌似是左上角)。

在代码中加载xml中定义的动画:

Animation animation = AnimationUtils.loadAnimation(this, R.anim.view1);
button.startAnimation(animation); 

使用Animation的setAnimationListener方法可以给View动画添加监听。

7.1.2 自定义View动画

原理:继承Animation这个抽象类,然后重写它的initialize和applyTransformation方法,在initialize中做初始化,在applyTransformation中进行相应的矩阵变换即可。通常采用camera来简化矩阵变换的过程。自定义View动画的过程主要就是矩阵变换的过程。例子可参考APIDEMO中的Rotate3dAnimation效果。

7.1.3 帧动画

帧动画其实就是顺序播放一组预先定义好的图片。通过AnimationDrawable来使用帧动画。XML格式语法如下:

<?xml version="1.0" encoding="utf-8" ?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true|false">
<item android:drawable="@mipmap/ic_launcher" android:duration="500"/>
<item android:drawable="@mipmap/ic_launcher" android:duration="500"/>
<item android:drawable="@mipmap/ic_launcher" android:duration="500"/>
</animation-list> 

使用时直接作为View的背景并通过Drawable来播放即可。

button.setBackgroundResource(R.drawable.view2);
AnimationDrawable drawable=(AnimationDrawable)button.getBackground();
drawable.start(); 

7.2 View动画的特殊使用场景

7.2.1 LayoutAnimation

作用于ViewGroup,为ViewGroup指定一个动画,这样当它的子元素出场时都会具有这种动画效果。

步骤:

(1)定义LayoutAnimation

<?xml version="1.0" encoding="utf-8" ?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.5"
android:animationOrder="normal"
android:animation="@anim/anim_item"/> 

android:delay 子元素开始动画的时间延迟,例如子元素设置duration为200ms,则0.5表示每个子元素都需要延迟100ms开能开始播放动画,即第一个经过100ms开始播放,第二个就得经过200ms开始播放,第三个就得经过300ms开始播放,以此类推。

android:animationOrder 子元素动画顺序,normal(顺序显示),reverse(逆向显示),random(随机)。

(2)为子元素指定动画

<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:interpolator="@android:anim/accelerate_interpolator"
android:shareInterpolator="true">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<translate
android:fromXDelta="500"
android:toYDelta="0" />
</set> 

(3)为ViewGroup指定android:layoutAnimation属性

android:layoutAnimation="@anim/anim_layout" 

或者通过LayoutAnimationController来为ViewGroup指定动画。

Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_item);

LayoutAnimationController controller=new LayoutAnimationController(animation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
linearlayout.setLayoutAnimation(controller); 

7.2.2 Activity的切换效果

使用overridePendingTransition(int enterAnim, int exitAnim)方法,注意这个方法必须在startActivity或者finish之后被调用才能生效。

enterAnim——Activity被打开时的动画

exitAnim——Activity退出时的动画

启动Activity:

Intent intent =new Intent(this,TestActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim); 

退出Activity:

@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
} 

7.3 属性动画

API等级必须大于等于11,存放路径为res/animator/目录下,属性动画可以对任何对象做动画,常见的有ValueAnimator、ObjectAnimator。

7.3.1 使用属性动画

属性动画默认时间间隔为300ms,默认帧率为10ms/帧,可以达到在一个时间间隔内完成对象从一个属性值到另一个属性值的改变。如果想要属性动画兼容低版本系统,需要使用NineOldAndroids这个开源动画库。

举例说明如何使用属性动画:

(1)改变一个对象的translationY属性,让其沿着Y轴向上平移一段距离:它的高度。
ObjectAnimator.ofFloat(myObject,"translationY",-myObject.getHeight());

(2)改变一个View的背景色,让其背景色在3秒内实现用0xFFFF8080到0xFF8080FF的渐变,动画无限循环并加反转效果。

ValueAnimator colorAnim=ObjectAnimator.ofInt(this,"backgroundColor",0xFFFF8080,0xFF8080FF);
colorAnim.setDuration(3000);
colorAnim.setEvaluator(new ArgbEvaluator());
colorAnim.setRepeatCount(ValueAnimator.INFINITE);
colorAnim.setRepeatMode(ValueAnimator.REVERSE);
colorAnim.start(); 

属性动画的XML格式语法如下:

<?xml version="1.0" encoding="utf-8" ?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially|together"><!--together:子动画同时播放。sequentially:自动化按照先后顺序依次播放-->
<objectAnimator
android:duration="int"<!--动画时长-->
android:propertyName="string"<!--属性名称-->
android:repeatCount="int"<!--重复次数-->
android:repeatMode="restart|reverse"<!--重复模式-->
android:startOffset="int"<!--延迟时间-->
android:valueFrom="float|int|color"<!--属性起始值-->
android:valueTo="float|int|color"<!--属性结束值-->
android:valueType="colorType|intType|floatType|pathType" /><!--属性类型-->
<animator
android:duration="int"
android:repeatCount="int"
android:repeatMode="restart|reverse"
android:startOffset="int"
android:valueFrom="float|int|color"
android:valueTo="float|int|color"
android:valueType="colorType|intType|floatType|pathType" />
</set> 

android:repeatCount 动画的循环次数,默认为0,-1为无限循环;

android:repeatMode repeat:连续重复;reverse:逆向重复(第一次播放完后,第二次倒着播放,第三次在重头开始播如此反复)。

在XML中定义好属性动画后在java代码中就可以使用了

AnimatorSet set=(AnimatorSet) AnimatorInflater.loadAnimator(context,R.anim.property_animator);
set.setTarget(button);
set.start(); 

实际开发中建议使用代码来实现属性动画,不要使用xml的方式。

7.3.2 理解插值器和估值器

插值器:根据时间流逝的百分比来计算出当前属性值改变的百分比;

估值器:根据当前属性的百分比来计算改变后的属性值。

7.3.3 属性动画监听器

AnimatorListener监听动画的开始、结束、取消、重复播放;

AnimatorUpdateListener 监听整个动画过程。

7.3.4 对任意属性做动画

对object的属性abc做动画,如果想让动画生效需要满足一下两个条件:

(1)object必须要提供setAbc方法,如果动画的时候没有传递初始值,那么还得提供getAbc方法,否则程序直接crash;

(2)object的setAbc对属性abc所做的改变必须能够通过某种方法反映出来,比如带来UI的改变。

如何给一个原始对象添加动画可参见p285页的方法2;

7.3.5 属性动画的工作原理

属性动画要求动画作用的对象提供该属性的set方法,属性动画根据你传递的该属性的初始值和最终值,以及动画的效果多次去掉用set方法。每次 传递给set方法的值都是不一样的,确切来说是随着时间的推移,所传递的值越来越接近最终值。如果动画的时候没有传递初始值,那么还要提供get方法,因 为系统要去获取属性的初始值。

7.4 使用动画的注意事项

注 意View动画是对View的影像做动画,并不是真正改变View的状态,因此有时候会出现动画完成后View无法隐藏的现象,即 setVisibility(View.GONE)失效了,这个时候只要调用view.clearAnimation()清除View动画即可解决此问 题。

将View移动(平移)后,在Android3.0以前的系统上,不管是View动画还是属性动画,新位置均无法触发单击事件,同时,老位置仍 然可以触发单击事件。尽管View已经在视觉上不存在了,将View移回原位置以后,原位置的单击事件继续生效。从3.0开始,属性动画的单击事件触发位 置为移动后的位置,但是View动画仍然在原位置。

关于Android开发艺术探索学习笔记(七)就给大家介绍这么多,后续还会持续更新android艺术探索相关知识,请大家持续关注本站,谢谢。

(0)

相关推荐

  • android源码探索之定制android关机界面的方法

    本文实例讲述了android源码探索之定制android关机界面的方法.分享给大家供大家参考.具体如下: 在Android系统中,长按Power键默认会弹出对话框让你选择"飞行模式","静音","关机"等功能.如下图所示: 但这些功能都对Android-x86和其他终端产品就没什么必要了.本文就简单介绍下如何定制关机界面. 我的目标是长按Power键,将会关机,弹出"设备将要关机"选择对话框.如果可以选择"是&quo

  • Android开发艺术探索学习笔记(七)

    第七章 Android动画深入分析 Android的动画分为三种:View动画,帧动画,属性动画.帧动画属于View动画. 7.1 View动画 View动画的作用对象是View,共有四种动画效果:平移(Translate),缩放(Scale),旋转(Rotate),透明度(Alpha). 7.1.1 View动画的种类 View动画的保存路径:res/anim/filename.xml.XML格式语法如下: <?xml version="1.0" encoding="

  • Android自定义控件之开关按钮学习笔记分享

    今天来讲讲自定义单个控件,就拿开关按钮来讲讲,相信大家见了非常多这样的了,先看看效果: 我们可以看到一个很常见的开关按钮,那就来分析分析. 首先: 这是由两张图片构成: ①一张为有开和关的背景图片 ②一张为控制开和关的滑动按钮 第一步: 写个类继承View,并重写几个方法: 第一个为构造函数,重写一个参数的函数和两个参数的函数就够了,因为两个参数的函数能够使用自定义属性 第二个为控制控件的大小–>protected void onMeasure(int widthMeasureSpec, int

  • Android手势密码view学习笔记(一)

    刚接触Android的时候看到别人写的手势密码view,然后当时就在想,我什么时候才能写出如此高端的东西?? 没关系,不要怕哈,说出这样话的人不是你技术不咋地而是你不愿意花时间去研究它,其实也没有那么难哦(世上无难事,只怕有心人!),下面我们就一步一步实现一个手势密码view. 想必都看过手势密码view,但我们还是看看我们今天要实现的效果吧: 上面是一个手势view的提示view,下面是一个手势view. 用法: <com.leo.library.view.GestureContentView

  • Android手势密码view学习笔记(二)

    我们还是接着我们上一篇博客中的内容往下讲哈,上一节 Android手势密码view笔记(一)我们已经实现了我们的IndicatorView指示器view了: 下面我们来实现下我们的手势密码view: 实现思路: 1.我们照样需要拿到用户需要显示的一些属性(行.列.选中的图片.未选中的图片.错误显示的图片.连接线的宽度跟颜色......). 2.我们需要根据手势的变换然后需要判断当前手指位置是不是在某个点中,在的话就把该点设置为选中状态,然后每移动到两个点(也就是一个线段)就记录该两个点. 3.最

  • 《javascript设计模式》学习笔记七:Javascript面向对象程序设计组合模式详解

    本文实例讲述了Javascript面向对象程序设计组合模式.分享给大家供大家参考,具体如下: 概述 关于组合模式的定义:组合模式(Composite Pattern)有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦.来自百度百科:http://baike.baidu.com/view/3591789.htm 其实从面向对象之五之后,与javascript本身关系不是很大,更

  • python网络编程学习笔记(七):HTML和XHTML解析(HTMLParser、BeautifulSoup)

    一.利用HTMLParser进行网页解析 具体HTMLParser官方文档可参考http://docs.python.org/library/htmlparser.html#HTMLParser.HTMLParser 1.从一个简单的解析例子开始 例1: test1.html文件内容如下: 复制代码 代码如下: <html> <head> <title> XHTML 与 HTML 4.01 标准没有太多的不同</title> </head> &l

  • SQL学习笔记七函数 数字,日期,类型转换,空值处理,case

    数字函数 ABS():求绝对值. CEILING():舍入到最大整数. FLOOR():舍入到最小整数. ROUND():四舍五入 ROUND(A,B)A是要处理的数,B是精确到小数点后第几位 LEN():计算字符串长度 LOWER().UPPER():转小写.大写 LTRIM():字符串左侧的空格去掉 RTRIM():字符串右侧的空格去掉 SUBSTRING(string,start_position,length) string是待处理字符串,start_position是开始截的个数,le

  • javascript学习笔记(七) js函数介绍

    1.函数内部属性 arguments arguments用来保存函数的参数,arguments.callee指向拥有arguments对象的函数 复制代码 代码如下: //阶乘 function factorial(num) { if (num <= 1) { return 1; } else { return num*arguments.callee(num-1); //用agreements.callee代替 } } var trueFactorial = factorial; factor

  • Android中Binder详细学习心得

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解Android 卷Ⅰ,Ⅱ,Ⅲ>中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能需要有一定Android开发基础和项目经验的同学才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师. 前言 上一次还不如不说去面试了呢,估计是挂了,数据结构与算

  • Android开发之无痕过渡下拉刷新控件的实现思路详解

    相信大家已经对下拉刷新熟悉得不能再熟悉了,市面上的下拉刷新琳琅满目,然而有很多在我看来略有缺陷,接下来我将说明一下存在的缺陷问题,然后提供一种思路来解决这一缺陷,废话不多说!往下看嘞! 1.市面一些下拉刷新控件普遍缺陷演示 以直播吧APP为例: 第1种情况: 滑动控件在初始的0位置时,手势往下滑动然后再往上滑动,可以看到滑动到初始位置时滑动控件不能滑动. 原因: 下拉刷新控件响应了触摸事件,后续的一系列事件都由它来处理,当滑动控件到顶端的时候,滑动事件都被下拉刷新控件消费掉了,传递不到它的子控件

随机推荐