Android Animation
2016-03-12 16:28
423 查看
1、Android Animation设计模式
Android的架构中用了很多的设计模式,Android的动画模型感触颇深,笔者之前开发过C++的动画模型,动画的模型和具体的元素耦合在一起,代码混乱,难以维护,使用复杂度高,可复用性低。
动画自成体系,和view通过接口交互,既具备模块隔离性,又保证了充分的扩展性。
至于实现view动画的细节实现,有机会还需要仔细研究下,刚入手重点还放在应用层面。
2、Android动画
Android动画整体可范围三类:view animation,drawable animation,property animation
2.1 view animation
View Animation只能应用于view对象,并且要注意的一点,对于View Animation,它只是改变了View对象绘制的位置,并没有改变View对象本身。比如,你定义了一个View,属性为(x:100,y:100,width:100,height:100),有一个动画使其变为(x:100,y:100,width:50,width:50),在动画过程中Button的点击区域仍然是(x:100,y:100)->(200,200).
View Animation支持支持四种动画效果,TranslateAnimation,ScaleAnimation,RotateAnimation,AlphaAnimation。动画的定义既可以通过XML方式来定义,也可以通过动态代码方式来创建。
单个View可以同时设置多个动画,默认多个动画是同时进行的,可以通过startOffset属性设置各个动画的开始偏移(开始时间)来达到动画顺序播放的效果。
通过XML方式定义View动画,需要在res/anim文件夹内创建xml文件,如下所示:
在代码中,加载XML文件实例化Animation,指定给指定的View即可。
XML文件的根元素可以为:,,,,(表示以上几个动画的集合,set可以嵌套,默认set内动画元素同时执行)
还可以通过代码方式定义动画
2.2 Drawable Animation
Drawable Animation通过顺序播放一组图片来实现动画的效果,使用方法如下:
在res/drawable/目录下新建Drawable
调用逻辑如下:
2.3 属性动画
属性动画是API 11后引入的,它扩展了动画的作用对象,可以对任何对象做动画,同时扩展了动画效果,可以实现更为绚丽的效果。属性动画几乎无所不能,只有对象有这个属性,就可以针对它做动画。在API 11版本之前,可以采用开源动画库nineoldandroids兼容以前版本。
2.3.1 属性动画的基础用法
属性动画中比较常用的几个类:ValueAnimator、ObjectAnimator、AnimatorSet。
与View动画一样,属性动画也有两种创建方法:通过代码创建和通过XML创建。
1)实现button上下平移的动画。
2) 改变View的背景色,实现在3s内从0xFFFF8080到0xFF8080FF的渐变,动画会无限重复。
3) 动画集合,5s内对View的旋转、平移、缩放和透明度都进行改变。
通过XML创建
属性动画需要定义在res/animator/目录下,格式如下:
使用属性动画的方式也很简单
2.3.2 属性动画的扩展
属性动画的Interpolator和TypeEvaluator很重要,通过自定义这两个接口可以实现千奇百怪的动画效果。
LinearInterpolator的源码:
IntEvaluator的源码
属性动画还提供了AnimatorUpdateListener和AnimatorListener两个监听器,用来监听动画的播放过程。
AnimatorLister的定义如下:
AnimatorUpdateListener的定义如下:
2.3.3 对任意属性做动画
针对Object属性abc的属性动画要生效,必须同时满足两个条件:
1) Object必须要提供setAbc的方法,如果动画的时候没有传递初始值,还必须提供getAbc的方法,因为系统要去取Abc属性的初始值(该条不满足,程序直接crash)
2)Object的setAbc方法对属性abc的改变必须能够通过某种方式反映出来,比如会带来UI改变之类的(不满足这条,动画无效果但不会crash)
如何给对象属性添加set和get方法,官方文档提供三个解决方法:
1、如果有权限的话,给你的对象加上get和set方法;
简单有效,但往往我们没有权限。
2、用一个类包装原始对象,间接为其提供get和set方法;
3、采用ValueAnimator, 监听动画过程,自己实现属性的改变。
参考资料:
Android的架构中用了很多的设计模式,Android的动画模型感触颇深,笔者之前开发过C++的动画模型,动画的模型和具体的元素耦合在一起,代码混乱,难以维护,使用复杂度高,可复用性低。
动画自成体系,和view通过接口交互,既具备模块隔离性,又保证了充分的扩展性。
至于实现view动画的细节实现,有机会还需要仔细研究下,刚入手重点还放在应用层面。
2、Android动画
Android动画整体可范围三类:view animation,drawable animation,property animation
2.1 view animation
View Animation只能应用于view对象,并且要注意的一点,对于View Animation,它只是改变了View对象绘制的位置,并没有改变View对象本身。比如,你定义了一个View,属性为(x:100,y:100,width:100,height:100),有一个动画使其变为(x:100,y:100,width:50,width:50),在动画过程中Button的点击区域仍然是(x:100,y:100)->(200,200).
View Animation支持支持四种动画效果,TranslateAnimation,ScaleAnimation,RotateAnimation,AlphaAnimation。动画的定义既可以通过XML方式来定义,也可以通过动态代码方式来创建。
单个View可以同时设置多个动画,默认多个动画是同时进行的,可以通过startOffset属性设置各个动画的开始偏移(开始时间)来达到动画顺序播放的效果。
通过XML方式定义View动画,需要在res/anim文件夹内创建xml文件,如下所示:
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/linear_interpolator" android:duration="150" android:fromDegrees="0.0" android:toDegrees="-225.0" android:pivotX="50.0%" android:pivotY="50.0%" android:fillAfter="true" android:fillEnabled="true"> </rotate>
在代码中,加载XML文件实例化Animation,指定给指定的View即可。
Button mButton = (Button)findViewById(R.id.button1); Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate_button_in); mButton.startAnimation(animation);
XML文件的根元素可以为:,,,,(表示以上几个动画的集合,set可以嵌套,默认set内动画元素同时执行)
还可以通过代码方式定义动画
Button mButton = (Button)findViewById(R.id.button1); AlphaAnimation alphaAnimation = new AlphaAnimation(0,1); alphaAnimation.setDuration(200); mButton.startAnimation(alphaAnimation);
2.2 Drawable Animation
Drawable Animation通过顺序播放一组图片来实现动画的效果,使用方法如下:
在res/drawable/目录下新建Drawable
<?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/image1" android:duration="500" /> <item android:drawable="@drawable/image2" android:duration="500" /> <item android:drawable="@drawable/image3" android:duration="500" /> </animation-list >
调用逻辑如下:
Button mButton = (Button)findViewById(R.id.button1); mButton.setBackgroundResource(R.drawable.frame_animation); AnimationDrawable drawable = (AnimationDrawable)mButton.getBackground(); drawable.start();
2.3 属性动画
属性动画是API 11后引入的,它扩展了动画的作用对象,可以对任何对象做动画,同时扩展了动画效果,可以实现更为绚丽的效果。属性动画几乎无所不能,只有对象有这个属性,就可以针对它做动画。在API 11版本之前,可以采用开源动画库nineoldandroids兼容以前版本。
2.3.1 属性动画的基础用法
属性动画中比较常用的几个类:ValueAnimator、ObjectAnimator、AnimatorSet。
与View动画一样,属性动画也有两种创建方法:通过代码创建和通过XML创建。
1)实现button上下平移的动画。
Button aniBtn = (Button)findViewById(R.id.btn_anim); ValueAnimator alphaAnim = ObjectAnimator.ofFloat(aniBtn, "translationY", 0,90); alphaAnim.setDuration(5000); alphaAnim.setRepeatCount(ValueAnimator.INFINITE); alphaAnim.start();
2) 改变View的背景色,实现在3s内从0xFFFF8080到0xFF8080FF的渐变,动画会无限重复。
ValueAnimator colorAnim = ObjectAnimator.ofInt(customView, "backgroundColor",0xFFFF8080,0xFF8080FF); colorAnim.setDuration(3000); colorAnim.setEvaluator(new ArgbEvaluator()); colorAnim.setRepeatCount(ValueAnimator.INFINITE); colorAnim.start();
3) 动画集合,5s内对View的旋转、平移、缩放和透明度都进行改变。
AnimatorSet set = new AnimatorSet(); set.playTogether( ObjectAnimator.ofFloat(customView, "rotationX", 0, 360); ObjectAnimator.ofFloat(customView, "rotationY", 0, 180); ObjectAnimator.ofFloat(customView, "translationX", 0, 90); ObjectAnimator.ofFloat(customView, "translationY", 0, 90); ObjectAnimator.ofFloat(customView, "scaleX", 1, 1.5f); ObjectAnimator.ofFloat(customView, "scaleY", 1, 0.5f); ObjectAnimator.ofFloat(customView, "alpha", 1, 0.25f,1); ); set.setDuration(5000).start();
通过XML创建
属性动画需要定义在res/animator/目录下,格式如下:
<set android:ordering=["together"|"sequentially"]> <objectAnimator android:propertyName="string" android:duration="int" android:valueFrom="float|int|color" android:valueTo="float|int|color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat|reverse"] android:valueType=["intType|floatType"]/> <Animator android:duration="int" android:valueFrom="float|int|color" android:valueTo="float|int|color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat|reverse"] android:valueType=["intType|floatType"]/> <set> ... </set> </set>
使用属性动画的方式也很简单
AnimatorSet set=(AnimatorSet)AnimatorInflater.loadAnimator(customContext,R.anim.property_animator); set.setTarget(mButton); set.start();
2.3.2 属性动画的扩展
属性动画的Interpolator和TypeEvaluator很重要,通过自定义这两个接口可以实现千奇百怪的动画效果。
LinearInterpolator的源码:
public class LinearInterpolator implements Interpolator{ public LinearInterpolator(){ } public LinearInterpolator(Context context, AttributeSet attrs)(){ } public float getInterpolation(float input){ return input; } }
IntEvaluator的源码
public class IntEvaluator implements TypeEvaluator<Integer>{ public Integer evaluate(float fraction, Integer startValue, Integer endValue){ int startInt = startValue; return (int)(startInt + fraction*(endValue-startValue)) } }
属性动画还提供了AnimatorUpdateListener和AnimatorListener两个监听器,用来监听动画的播放过程。
AnimatorLister的定义如下:
public static interface AnimatorLister{ void onAnimationStart(Animator animation); void onAnimationEnd(Animator animation); void onAnimationCancel(Animator animation); void onAnimationRepeat(Animator animation); }
AnimatorUpdateListener的定义如下:
public static interface AnimatorUpdateListener{ void onAnimationUpdate(ValueAnimator animation); }
2.3.3 对任意属性做动画
针对Object属性abc的属性动画要生效,必须同时满足两个条件:
1) Object必须要提供setAbc的方法,如果动画的时候没有传递初始值,还必须提供getAbc的方法,因为系统要去取Abc属性的初始值(该条不满足,程序直接crash)
2)Object的setAbc方法对属性abc的改变必须能够通过某种方式反映出来,比如会带来UI改变之类的(不满足这条,动画无效果但不会crash)
如何给对象属性添加set和get方法,官方文档提供三个解决方法:
1、如果有权限的话,给你的对象加上get和set方法;
简单有效,但往往我们没有权限。
2、用一个类包装原始对象,间接为其提供get和set方法;
private void performAnimate(){ ViewWrapper wrapper = new ViewWrapper(mButton); ObjectAnimator.ofInt(wrapper,"width",500).setDuration(5000).start(); } @override public void onClick(View v){ if (v == mButton){ performAnimate(); } } private static class ViewWrapper { private View mTarget; public ViewWrapper(View target){ mTarget = target; } public int getWidth(){ return mTarget.getLayoutParam().width; } public void setWidth(int width){ mTarget.getLayoutParam().width = width; mTarget.requestLayout(); } }
3、采用ValueAnimator, 监听动画过程,自己实现属性的改变。
private void performAnimate(final View target, final int start, final int end){ ValueAnimator valueAnimator = ValueAnimator.ofInt(1,100); valueAnimator.addUpdateListener(new AnimatorUpdateListener(){ private IntEvaluator mEvaluator = new IntEvaluator(); @override public void onAnimationUpdate(ValueAnimator animator){ int currentValue = (Interge)animator.getAnimateValue(); float fraction = animator.getAnimateFraction(); target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end); target.requestLayout(); } }); valueAnimator.setDuration(5000).start(); } @override public void onClick(View v){ if (v == mButton){ performAnimate(mButton,mButton.getWidth(),500); } }
参考资料:
相关文章推荐
- Android 混淆代码总结
- Android Sqlite使用中注意事项
- Android学习之自定义控件之图片带文字的View
- Android MVVM的沉思
- Android开发之Android SDK Mannager更新失败
- 【读书笔记】【Android 开发艺术探索】第 6 章 Android 的 Drawable
- android TIF HAL层代码分析
- Android双向滑动冲突解决方案
- Android手动打包
- 【Music】横屏歌词显示效果不好
- 【Android测试】【随笔】测试分析——语法测试
- TUNA下载Android源码
- ColorStateList实现TextView文字按下时颜色变化
- Android基础知识之控件系列(2)——Button及自定义背景
- Android之Dialog详解
- android:限制EditText输入位数
- android自定义控件(二),简易的数值输入器
- android之layout_gravity 和 gravity 两者之间的区别
- Android SlidingMenu使用详解
- Android Studio 运行 遇到:Failed to read key from keystore