最近在学习《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);
待续。。。。。。