Android动画总结(属性动画,补间动画,帧动画)
来源:互联网 发布:地图坐标编程软件 编辑:程序博客网 时间:2024/05/16 10:20
Android 动画总结
csdn图片可能有问题,可以看原文地址:
http://www.jianshu.com/p/d98e79486373
动画分类
Android中动画大概分为3类:
TweenAnimation(补间动画)
- TranslateAnimation
- ScaleAnimation
- RotateAnimation
- AlphaAnimation
FrameAnimation(帧动画)
- PropertyAnimation(属性动画)
PropertyAnimation属性动画
先来看属性动画,这是潮流,也是google推荐使用的。
属性动画和一般的View动画的重要区别在于:
1. 属性动画控制的是实实在在的属性,但是View动画只是产生一个动画,并没有改变控件的属性。
2. View动画只能控制View的属性,属性动画可以控制所有属性,只要这个属性有get/set 方法,是什么意思呢?
例如 我们查看ImageView的源码,可以看到它有一个私有属性叫 alpha,表示透明度,同时有 setAlpha()/getAlpha() 方法,所有我们就可以通过属性动画来修改ImageView的Alpha的值来完成动画。
那么问题来了,到底动画是怎么产生的呢?简单的说就是,在动画执行前你需要为动画设置初始值,结束值,动画时间(这是3个最基本的值),那么ValueAnimator类就可以通过这3个值计算出一串连续的数字,表示动画的过程。
例如:alpha值 from 0 to 255,如果时间设置成 255秒,那么 ValueAnimator产生的值将为每秒变化1,0,1,2,3,4,5,6…,然后将这些值通过 setAlpha() 设置给ImageView,就完成了动画。 当然这个例子比较奇葩,但是我觉得比较好理解。
那么怎么来实践我说的呢?我们来看一个例子:
ValueAnimator
这是ValueAnimator的初级用法,通过 ofFloat() 方法设置起始x坐标,起始x+100,起始x坐标,就是一个在x轴上一个来回100px的动画。区间是1000ms,注意为了将动画与控件相关联(动画都是需要应用到控件上),需要添加一个 AnimatorUpdateListener,这个回调就是用来产生一系列的中间值,然后我们在回调中将中间值设置给我们的ImageView,那么动画就完成了。
最后我们还是用Log将中间值都打印了出来,就更容易理解ValueAnimator就是用来产生一个值变化的序列的作用。当然这里使用的是默认的线性插值器,变化率是均匀的,如果使用其他插值器,还可以产生不均匀的效果。
float fromX = ivLogo.getTranslationX();ValueAnimator va = ValueAnimator.ofFloat(fromX, fromX + 100f, fromX);va.setDuration(1000);va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float v = (float) animation.getAnimatedValue(); ivLogo.setTranslationX(v); Log.d(TAG, "v:" + v); }});va.start();
效果图:
打印出来的Log:
D/ANIMATION: v:0.0D/ANIMATION: v:0.14258027D/ANIMATION: v:0.53691864D/ANIMATION: v:1.2311637D/ANIMATION: v:2.2070706D/ANIMATION: v:3.3803642D/ANIMATION: v:4.894352...D/ANIMATION: v:84.35657D/ANIMATION: v:89.65131D/ANIMATION: v:94.66184D/ANIMATION: v:100.0D/ANIMATION: v:94.66184D/ANIMATION: v:89.651306D/ANIMATION: v:84.35657...D/ANIMATION: v:6.679535D/ANIMATION: v:4.894348D/ANIMATION: v:3.380371D/ANIMATION: v:2.2070618D/ANIMATION: v:1.2311707D/ANIMATION: v:0.53691864D/ANIMATION: v:0.14257813D/ANIMATION: v:0.0
理解了这个,我们就可以来看看下一个更加使用的类
ObjectAnimator
public final class ObjectAnimator extends ValueAnimator{...}
查看源码就知道,ObjectAnimator是继承于ValueAnimator的,ObjectAnimator使用起来更加简单,因为ValueAnimator还需要我们自己去回调,ObjectAnimator不需要写回调,只需要把要设置的属性,控件,区间等内容告诉它,它自己帮我们完成动画。
例子:
float fromX = ivLogo.getTranslationX();ObjectAnimator oa = ObjectAnimator.ofFloat(ivLogo, "translationX", fromX, fromX + 100f, fromX);oa.setDuration(300);oa.start();oa.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); }});
效果和使用 ValueAnimator 是一样的,所以就不贴图了。刚刚我们说不需要回调,但是这里又写了一个回调的Listener是什么意思呢?大家大可把这个删掉,我这里加上主要是为了说明如果想监听 动画结束,动画开始… 等中间过程,ObjectAnimator也可以做到。只需要添加这个 AnimatorListenerAdapter 抽象类。至于这里为什么是抽象类,大家打开源码就可以明白,为了不实现回调的所有方法,特别加了一个抽象类实现 AnimatorListener 接口,这样就可以想覆盖什么方法就覆盖什么方法,不需要全部都覆盖。这也可以理解为 设计模式中的适配器模式吧,原接口不符合我的要求,我需要一个适配器来完成转换
AnimatorSet
如果上面两个都理解了,那么这个就好理解了。AnimatorSet顾名思义就是动画的集合,我们要将几个属性动画放在一起运行,或者按照序列执行,或者按任意顺序执行都可以实现,看看例子:
ObjectAnimator oaScaleX = ObjectAnimator.ofFloat(ivLogo, "scaleX", 0, 1);ObjectAnimator oaScaleY = ObjectAnimator.ofFloat(ivLogo, "scaleY", 0, 1);ObjectAnimator oaRotation = ObjectAnimator.ofFloat(ivLogo, "rotation", 0, 360);ObjectAnimator oaAlpha = ObjectAnimator.ofFloat(ivLogo, "alpha", 1, 0);AnimatorSet as = new AnimatorSet();as.play(oaScaleX).with(oaScaleY).with(oaRotation);as.play(oaAlpha).after(oaRotation);as.setDuration(1000);as.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); ivLogo.setAlpha(1.0f); Log.d(TAG, "finish:" + ivLogo.getAlpha()); }});as.start();
首先构造了4个 ObjectAnimator对象,分别是沿X轴变形,沿Y轴变形,旋转,透明度,然后我们让前3个一起执行,之后在执行渐变,最后添加一个动画结束回调,将Alpha设置为1,表示不透明,否则我们的控件就看不见了。
效果图:
使用xml文件配置属性动画
android的套路,一定会允许你使用xml的方式来配置动画,所以我们看看怎么配置:
res 文件夹下新建文件夹 animator, 然后创建一个 动画xml文件:
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="2000" android:propertyName="x" android:valueFrom="0" android:valueTo="200" android:valueType="floatType" /> <objectAnimator android:duration="2000" android:propertyName="rotation" android:valueFrom="0" android:valueTo="360" android:valueType="floatType" /> <objectAnimator android:duration="2000" android:propertyName="x" android:valueFrom="200" android:valueTo="400" android:valueType="floatType" /></set>
android:ordering="sequentially"
表示依次执行,
android:propertyName="rotation"
表示修改的属性值
android:valueType="floatType"
表示属性值类型
其他的都好理解了。
然后在代码中使用:
Animator animator = AnimatorInflater.loadAnimator(PropertyActivity.this, R.animator.animator_1);animator.setTarget(ivLogo);animator.start();
效果图:
使用插值器
我们知道 ValueAnimator就是用来产生一些动画属性中间值,但是默认是均匀变化的,插值器就是要使得产生的中间序列非均匀化,当然不仅是非均匀这么简单,还有很多特效:
下面是官网提供的一些插值器,大家都可以试试,我这里只是抛砖引玉,展示最简单的用法:
使用方法:
float fromX = ivLogo.getTranslationX();ObjectAnimator oa = ObjectAnimator.ofFloat(ivLogo, "translationX", fromX, fromX + 100, fromX);oa.setInterpolator(new BounceInterpolator());oa.setDuration(1000);oa.start();
只比前面多了一行:oa.setInterpolator(new BounceInterpolator());
效果图:
TweenAnimation补间动画
如果上面的属性动画你都理解了,那么补间动画就更好理解了:
通过代码,和xml配置创建Animation
btnAnimation.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Animation animation = new TranslateAnimation(0, 200, 0, 200); animation.setDuration(1000); animation.setFillAfter(true); ivLogo.startAnimation(animation); }});btnXml.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Animation animation = AnimationUtils.loadAnimation(TweenActivity.this, R.anim.anim1); animation.setDuration(1000); animation.setFillAfter(true); ivLogo.startAnimation(animation); }});ivLogo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d(TAG, "onClick"); }});
anim1.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_decelerate_interpolator"> <translate android:fromXDelta="200" android:fromYDelta="200" android:toXDelta="0" android:toYDelta="0" /></set>
代码很简单,看一下就明白了,这里给 ivLogo添加了一个onclick事件,是为了说明tween动画修改的不是view的真实属性,怎么说呢?如果点击第一个动画,ivLogo的位置相对于原来的位置已经偏离到 (+200, +200) 的位置,但是这个时候如果依然点击 ivLog原位置,依然会打印 “onClick”, 所以其实View的位置属性是没有变化的。所以Tween动画修改的不是属性值,而只是产生的一个动画效果而已。
效果图:
学习Animation的话,关注比较多的应该是Animation的一些属性设置,大家感兴趣可以参考官网。
FrameAnimation帧动画
上面两个动画都与控件相关,但是帧动画就完全是图片的叠加。原理和 gif 动画 或者电影一样,是因为每一帧过的速度太快,眼睛来不及反应所以我们觉得是动画。
anim_frame.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/logo1" android:duration="100" /> <item android:drawable="@drawable/logo2" android:duration="100" /> <item android:drawable="@drawable/logo3" android:duration="100" /> <item android:drawable="@drawable/logo4" android:duration="100" /> <item android:drawable="@drawable/logo5" android:duration="100" /> <item android:drawable="@drawable/logo6" android:duration="100" /></animation-list>
- 根元素为 animation-list
- android:oneshot=”false” 表示动画一直循环执行
代码调用:
btnStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ivWifi.setImageResource(R.drawable.anim_frame); AnimationDrawable animationDrawable = (AnimationDrawable) ivWifi.getDrawable(); if (isRun) { animationDrawable.stop(); } else { animationDrawable.start(); } isRun = !isRun; }});
一个全局变量表示动画是否在执行,然后点击按钮时更换状态。
效果图:
总结
例子代码下载链接:
http://download.csdn.net/detail/u013647382/9648454
Android中提供了3种动画,以后的趋势还是属性动画,所以大家不要犹豫,快来钻研属性动画吧!
- Android 动画总结(补间动画,属性动画)
- Android动画总结(属性动画,补间动画,帧动画)
- android中的动画:帧动画、补间动画、属性动画
- Android动画:帧动画、补间动画、属性动画
- Android动画 帧动画、补间动画、属性动画 (一)
- Android动画 帧动画、补间动画、属性动画 (二)
- android 补间动画 属性动画 总结
- android补间动画,属性动画总结
- 属性动画,补间动画,帧动画
- 帧动画、补间动画、属性动画
- 帧动画&补间动画&属性动画
- 属性动画、帧动画、补间动画
- Android的帧动画、补间动画、属性动画
- android 帧动画,补间动画,属性动画区别
- Android属性动画和View动画(补间动画)
- Android中的动画(帧动画、补间动画、属性动画)
- android动画 -- 帧动画 补间动画
- Android动画-帧动画&补间动画
- SERVICE_STATUS结构各成员解析
- IOC(2)
- getopt()函数:分析命令行参数
- C#流程控制语句
- GreenDao 3.0使用
- Android动画总结(属性动画,补间动画,帧动画)
- iOS将汉字转成拼音
- thinkphp5的控制台的使用
- C#实现的CRC32算法
- linux 查看文件夹大小
- samd20 21 配置pwm 改变频率 占空比
- Android 调用系统Email发送带多附件的邮件
- unity实现单张纹理贴图的3种方法
- iperf