android属性动画
来源:互联网 发布:智慧树网络课程答案doc 编辑:程序博客网 时间:2024/06/05 22:32
因此Android系统在一开始的时候就给我们提供了两种实现动画效果的方式,逐帧动画(frame-by-frame animation)和补间动画(tweened animation)。逐帧动画的工作原理很简单,其实就是将一个完整的动画拆分成一张张单独的图片,然后再将它们连贯起来进行播放,类似于动画片的工作原理。补间动画则是可以对View进行一系列的动画操作,包括淡入淡出、缩放、平移、旋转四种。
然而自Android 3.0版本开始,系统给我们提供了一种全新的动画模式,属性动画(property animation),它的功能非常强大,弥补了之前补间动画的一些缺陷,几乎是可以完全替代掉补间动画了。
补间动画有一个缺陷,就是它只能够实现移动、缩放、旋转和淡入淡出这四种动画操作,那如果我们希望可以对View的背景色进行动态地改变呢?很遗憾,我们只能靠自己去实现了。说白了,之前的补间动画机制就是使用硬编码的方式来完成的,功能限定死就是这些,基本上没有任何扩展性可言。
补间动画还有一个致命的缺陷,就是它只是改变了View的显示效果而已,而不会真正去改变View的属性。什么意思呢?比如说,现在屏幕的左上角有一个按钮,然后我们通过补间动画将它移动到了屏幕的右下角,现在你可以去尝试点击一下这个按钮,点击事件是绝对不会触发的,因为实际上这个按钮还是停留在屏幕的左上角,只不过补间动画将这个按钮绘制到了屏幕的右下角而已,属性动画的实现机制是通过对目标对象进行赋值并修改其属性来实现的,那么之前所说的按钮显示的问题也就不复存在了,如果我们通过属性动画来移动一个按钮,那么这个按钮就是真正的移动了,而不再是仅仅在另外一个位置绘制了而已。
ValueAnimator
valueanimator动态改变一个值,利用这个值可以对view的任何属性设置动画:protected void testValueAnimtor(View view){ ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); anim.setDuration(3000); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float fValue = (float) animation.getAnimatedValue(); mtvTest.setAlpha(fValue); } }); anim.start();}
int值可以用ofInt来改变
ObjectAnimator
继承ValueAnimator,不用写监听,直接在参数里指定要执行动画的view和view的属性,但是它不是对任何属性都可以执行的,必须要相关属性有get/set方法才行,比如alpha,有get和setAlpha,当然,大部分属性都有get和set方法alpha从1到0再到1:
- ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
- animator.setDuration(5000);
- animator.start();
旋转360度
- ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
- animator.setDuration(5000);
- animator.start();
- float curTranslationX = textview.getTranslationX();
- ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX", curTranslationX, -500f, curTranslationX);
- animator.setDuration(5000);
- animator.start();
- ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f);
- animator.setDuration(5000);
- animator.start();
RepeatCount传入-1表示无限旋转,如果不设置Interpolator,有加速效果,两次旋转之间速度要重新从0开始,所以有停顿,不连续,要设置线性匀速加速才行
protected void testRepeatRotation(View view){ ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f); animator.setDuration(5000); animator.setInterpolator(new LinearInterpolator()); animator.setRepeatCount(-1); animator.start();}
组合动画
- after(Animator anim) 将现有动画插入到传入的动画之后执行
- after(long delay) 将现有动画延迟指定毫秒后执行
- before(Animator anim) 将现有动画插入到传入的动画之前执行
- with(Animator anim) 将现有动画和传入的动画同时执行
protected void testObjectAnimtorSet(View view){ ObjectAnimator moveIn = ObjectAnimator.ofFloat(view, "translationX", -500f, 0f); ObjectAnimator rotate = ObjectAnimator.ofFloat(view, "rotation", 0f, 360f); ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f, 1f); AnimatorSet animSet = new AnimatorSet(); animSet.play(rotate).with(fadeInOut).after(moveIn); animSet.setDuration(5000); animSet.start();}
Animator监听器
在很多时候,我们希望可以监听到动画的各种事件,比如动画何时开始,何时结束,然后在开始或者结束的时候去执行一些逻辑处理。这个功能是完全可以实现的,Animator类当中提供了一个addListener()方法,这个方法接收一个AnimatorListener,我们只需要去实现这个AnimatorListener就可以监听动画的各种事件了。
大家已经知道,ObjectAnimator是继承自ValueAnimator的,而ValueAnimator又是继承自Animator的,因此不管是ValueAnimator还是ObjectAnimator都是可以使用addListener()这个方法的。另外AnimatorSet也是继承自Animator的,因此addListener()这个方法算是个通用的方法。
添加一个监听器的代码如下所示:
- anim.addListener(new AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- }
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- }
- @Override
- public void onAnimationCancel(Animator animation) {
- }
- });
但是也许很多时候我们并不想要监听那么多个事件,可能我只想要监听动画结束这一个事件,那么每次都要将四个接口全部实现一遍就显得非常繁琐。没关系,为此Android提供了一个适配器类,叫作AnimatorListenerAdapter,使用这个类就可以解决掉实现接口繁琐的问题了,如下所示:
- anim.addListener(new AnimatorListenerAdapter() {
- });
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- }
- });
使用XML编写动画
我们可以使用代码来编写所有的动画功能,这也是最常用的一种做法。不过,过去的补间动画除了使用代码编写之外也是可以使用XML编写的,因此属性动画也提供了这一功能,即通过XML来完成和代码一样的属性动画功能。
通过XML来编写动画可能会比通过代码来编写动画要慢一些,但是在重用方面将会变得非常轻松,比如某个将通用的动画编写到XML里面,我们就可以在各个界面当中轻松去重用它。
如果想要使用XML来编写动画,首先要在res目录下面新建一个animator文件夹,所有属性动画的XML文件都应该存放在这个文件夹当中。然后在XML文件中我们一共可以使用如下三种标签:
- <animator> 对应代码中的ValueAnimator
- <objectAnimator> 对应代码中的ObjectAnimator
- <set> 对应代码中的AnimatorSet
那么比如说我们想要实现一个从0到100平滑过渡的动画,在XML当中就可以这样写:
- <animator xmlns:android="http://schemas.android.com/apk/res/android"
- android:valueFrom="0"
- android:valueTo="100"
- android:valueType="intType"/>
- <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType"
- android:propertyName="alpha"/>
另外,我们也可以使用XML来完成复杂的组合动画操作,比如将一个视图先从屏幕外移动进屏幕,然后开始旋转360度,旋转的同时进行淡入淡出操作,就可以这样写:
- <set xmlns:android="http://schemas.android.com/apk/res/android"
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="2000"
- android:propertyName="translationX"
- android:valueFrom="-500"
- android:valueTo="0"
- android:valueType="floatType" >
- </objectAnimator>
- <set android:ordering="together" >
- <objectAnimator
- android:duration="3000"
- android:propertyName="rotation"
- android:valueFrom="0"
- android:valueTo="360"
- android:valueType="floatType" >
- </objectAnimator>
- <set android:ordering="sequentially" >
- <objectAnimator
- android:duration="1500"
- android:propertyName="alpha"
- android:valueFrom="1"
- android:valueTo="0"
- android:valueType="floatType" >
- </objectAnimator>
- <objectAnimator
- android:duration="1500"
- android:propertyName="alpha"
- android:valueFrom="0"
- android:valueTo="1"
- android:valueType="floatType" >
- </objectAnimator>
- </set>
- </set>
- </set>
最后XML文件是编写好了,那么我们如何在代码中把文件加载进来并将动画启动呢?只需调用如下代码即可:
- Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);
- animator.setTarget(view);
- animator.start();
调用AnimatorInflater的loadAnimator来将XML动画文件加载进来,然后再调用setTarget()方法将这个动画设置到某一个对象上面,最后再调用start()方法启动动画就可以了,就是这么简单。
ViewPropertyAnimator的用法
ViewPropertyAnimator其实算不上什么高级技巧,它的用法格外的简单,只不过和前面所学的所有属性动画的知识不同,它并不是在3.0系统当中引入的,而是在3.1系统当中附增的一个新的功能,在低版本的模拟器里看不到动画效果(比如4.2.2)
我们都知道,属性动画的机制已经不是再针对于View而进行设计的了,而是一种不断地对值进行操作的机制,它可以将值赋值到指定对象的指定属性上。但是,在绝大多数情况下,我相信大家主要都还是对View进行动画操作的。Android开发团队也是意识到了这一点,没有为View的动画操作提供一种更加便捷的用法确实是有点太不人性化了,于是在Android 3.1系统当中补充了ViewPropertyAnimator这个机制。
那我们先来回顾一下之前的用法吧,比如我们想要让一个TextView从常规状态变成透明状态,就可以这样写:
1.
ObjectAnimator animator = ObjectAnimator.ofFloat(textview,
"alpha"
, 0f);
2.
animator.start();
那么下面我们就来看一下如何使用ViewPropertyAnimator来实现同样的效果,ViewPropertyAnimator提供了更加易懂、更加面向对象的API,如下所示:
1.
textview.animate().alpha(0f);
果然非常简单!不过textview.animate()这个方法是怎么回事呢?animate()方法就是在Android 3.1系统上新增的一个方法,这个方法的返回值是一个ViewPropertyAnimator对象,也就是说拿到这个对象之后我们就可以调用它的各种方法来实现动画效果了,这里我们调用了alpha()方法并转入0,表示将当前的textview变成透明状态。
怎么样?比起使用ObjectAnimator,ViewPropertyAnimator的用法明显更加简单易懂吧。除此之外,ViewPropertyAnimator还可以很轻松地将多个动画组合到一起,比如我们想要让textview运动到500,500这个坐标点上,就可以这样写:
1.
textview.animate().x(
500
).y(
500
);
如果要顺序执行,可以这样:
protected void testViewPropertyAnimator(final View view){ view.animate().setDuration(10000).alpha(0.5f).setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { view.animate().x(500).y(500).setDuration(10000); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } });}
- Android动画--属性动画
- android动画 -- 属性动画
- Android动画-属性动画
- Android动画【属性动画】
- Android动画--属性动画
- android属性动画--布局动画
- Android 动画之属性动画
- Android中的动画,属性动画
- android-属性动画、视图动画
- Android动画之属性动画
- android动画 属性动画详解
- Android笔记----动画、属性动画
- Android动画之属性动画
- android 动画 之 属性动画
- Android动画之---属性动画
- Android动画之属性动画
- Android动画--属性动画--基础
- Android动画(三):属性动画
- 使用RoboCopy 命令
- How Tomcat works之第十一章之ApplicationFilterChain
- 架构漫谈(四):如何做好架构之架构切分
- 记录一个分享页面的资源加载
- 【1】Java中怎么把int型的数字转换成char型的数字
- android属性动画
- 架构漫谈(五):什么是软件
- Java2.12.1实验1(联合编译)
- Centos7装zabbix 3
- 架构漫谈(六):软件架构到底是要解决什么问题?
- 视频框架Vitamio学习
- Java 内部类的实例化
- 架构漫谈(七):不要空设架构师这个职位,给他实权
- 哈夫曼树构造和编码方式