最近在学习《Android开发艺术探索》这本书,并且对第七章作了一个学习总结,以便自己加深印象。Android动画分为View动画、帧动画、属性动画。严格来讲,帧动画也属于View动画,只是它和常见的View动画在表现形式不一样而已View动画属于对各种场景对象做图像变换从而产生动画效果,属于渐进式动画,且支持自定义;帧动画是按一定顺序播放一系列图像产生的动画效果,可以理解为图片切换效果,尤其明显的缺点是图片过多过大会导致OOM。属性动画是动态的修改对象的属性从而达到动画的效果。这里分为两部分来讲:
一、View动画(包含了帧动画); 二、属性动画;
首先,View动画分为平移动画、缩放动画、旋转动画、透明动画四种表现形式:
名称 标签 子类 描述 平移动画 <translate> TranslateAnimation 移动View 缩放动画 <scale> ScaleAnimation 放大或者缩小View 旋转动画 <rotate> RotateAnimation 旋转View 透明度动画 <alpha> AlphaAnimation 改变View的透明度xml编写动画,xml文件放置于anim文件下面:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="true" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:zAdjustment="normal"> <!-- android:interpolator为动画集合指定插值器,配合android:shareInterpolator使用; android:shareInterpolator决定动画集合的动画是否共享同一个插值器 android:zAdjustment="normal" normal(0):正在播放的动画内容保持当前的Z轴顺序, top(1):在动画播放期间,强制把当前播放的内容放到其他内容的上面; bottom(-1):在动画播放期间,强制把当前播放的内容放到其他内容之下 --> <rotate android:fromDegrees="90" android:toDegrees="270" android:duration="1000" android:fillAfter="false"> <!-- android:fromDegrees="90" 起始角度 android:toDegrees="270" 结束角度 android:duration="1000" 动画时间 android:fillAfter="false" 动画结束以后View显示位置是否停留在结束位置 --> </rotate> <alpha android:fromAlpha="0.1" android:toAlpha="1" android:duration="1000" android:fillAfter="false"> <!-- android:fromAlpha="0.1" 开始的透明度 android:toAlpha="1" 结束的透明度 --> </alpha> <scale android:fromXScale="0.5" android:toXScale="1.5" android:fromYScale="0.5" android:toYScale="1.5" android:duration="1000" android:fillAfter="false"> <!-- android:fromXScale="0.5" X轴开始缩放的起始值; android:toXScale="1.5" X轴结束缩放的结束值 android:fromYScale="0.5" Y轴开始缩放的起始值; android:toYScale="1.5" Y轴结束缩放的结束值 --> </scale> <translate android:fromXDelta="100" android:toXDelta="200" android:fromYDelta="0" android:toYDelta="0" android:duration="1000" android:fillAfter="false" > <!-- android:fromXDelta="100" X方向平移的起点位置 android:toXDelta="200" X方向平移的终点位置 android:fromYDelta="0" Y方向平移的起点位置 android:toYDelta="0" Y方向平移的终点位置 --> </translate> </set>使用:
Animation animation = AnimationUtils.loadAnimation(this,R.anim.translate); btnDemo.startAnimation(animation);直接使用代码:
TranslateAnimation translateAnimation = new TranslateAnimation(100,200,0,0); // public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) // 该方法参数同xml里面一致 translateAnimation.setDuration(1000); translateAnimation.setFillAfter(false); btnDemo.startAnimation(translateAnimation);上面都是原生的动画,各位要是觉得不满意,还可以自定义View动画,不过现在很少使用,自己还可以自定义一个,下面是Android ApiDemos的一个自定义View动画,动画效果大家可以自己看demo:
package vicent.softb.hhqy.com.animationdemo; import android.graphics.Camera; import android.graphics.Matrix; import android.view.animation.Animation; import android.view.animation.Transformation; /** * Created by Administrator on 2016/8/25. */ public class Rotate3DAnimation extends Animation { private final float mFromDegeees; private final float mToDegeees; private final float mCenterX; private final float mCenterY; private final float mDepthz; private final boolean mReverse; private Camera camera; public Rotate3DAnimation(float fromDegrees,float toDegrees,float centerX,float centerY,float depthz,boolean reverse) { mFromDegeees = fromDegrees; mToDegeees = toDegrees; mCenterX = centerX; mCenterY = centerY; mDepthz = depthz; mReverse = reverse; } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); camera = new Camera(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); final float fromDegrees = mFromDegeees; float degrees = fromDegrees+(mToDegeees-fromDegrees)*interpolatedTime; final float centerX = mCenterX; final float centerY = mCenterY; final Camera mcamera = camera; final Matrix matrix = t.getMatrix(); mcamera.save(); if(mReverse) { mcamera.translate(0,0,mDepthz*interpolatedTime); } else { mcamera.translate(0,0,mDepthz*(1-interpolatedTime)); } mcamera.rotateY(degrees); mcamera.getMatrix(matrix); camera.restore(); matrix.preTranslate(-centerX,-centerY); matrix.postTranslate(centerX,centerY); } }接着是帧动画,帧动画类似于gif图片,默认重复播放,很好理解也很好用,但是切忌避免使用过多尺寸和过大的图片,OOM啊!! xml资源,记住这个是放在drawable文件夹下面的
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@mipmap/common_loading_0" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_1" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_2" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_3" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_4" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_5" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_6" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_7" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_8" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_9" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_10" android:duration="100"></item> <item android:drawable="@mipmap/common_loading_11" android:duration="100"></item> </animation-list> //对控件在布局的时候使用 android:background="@drawable/frame_animation"资源布置好了就可以使用了,
AnimationDrawable aniamtionDrawable = (AnimationDrawable) btnDemo.getBackground(); aniamtionDrawable.start();接下来是动画的一些使用场景,除了四种形式(平移、旋转、缩放、透明)外,View动画还可以在特殊的场景下使用:
1、动画过程监听
private void startCustomViewAnimation() { Animation animation = new Rotate3DAnimation(90,270,btnDemo.getX(),btnDemo.getY(),20,false); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { } @Override public void onAnimationRepeat(Animation animation) { } }); btnDemo.startAnimation(animation); }2、LayoutAnimation LayoutAnimation作用于Viewgroup,为Viewgroup指定一个动画,它的子元素出场就会具有这种效果了。 xml布局文件放置于drawable下面的anim文件下:
<?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/rotate"> <!-- android:delay 子元素开始动画的延迟时间 android:animationOrder 子元素动画的顺序 normal 排在前面的子元素先开始播放入场动画; reverse 逆向显示,排在后面的子元素开始播放入场动画; random 随机播放入场动画 --> </layoutAnimation> <!-- ------ --> //使用方法 <android.support.v4.view.ViewPager android:id="@+id/id_viewPager" android:layout_width="match_parent" android:layout_height="0dip" android:layout_weight="1" android:layoutAnimation="@anim/layout">这样就可以做到自带动画了,不需要额外的java代码了,但是也可以直接使用java代码来完成这个动画,但是资源文件一样还是需要的,如下:
Animation animation = AnimationUtils.loadAnimation(this,R.anim.layout); LayoutAnimationController controller = new LayoutAnimationController(animation,0.5f); controller.setOrder(LayoutAnimationController.ORDER_NORMAL); // 通过查看源码,ViewPager没有该方法,但是Viewgroup却有该方法,所以只有部分Viewgroup的子类才能使用java代码来加载该动画 // ViewPager.setLayoutAnimation(controller); ListView lv = new ListView(this); lv.setLayoutAnimation(controller);3、Activity的动画切换效果 Activity有默认的切换效果,但是也可以自定义,代码如下:
//enterAnim代表Activity打开时的动画资源 //exitAnim代表Activity退出时的动画效果 public void overridePendingTransition(int enterAnim, int exitAnim)该方法一般在startActivity方法之后调用,为Activity添加动画效果,也可以在finish方法之后调用,为自己定义退出的动画效果。
4、Fragment切换效果 这个动画效果有很多,但是这里简单说一个,说不定今后有特殊场景需要用到呢?
getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.alpha,R.anim.translate);待续。。。。。。