动画在工作中虽然用到的地方还不多,但是如果加上动画,效果还是很不错的。看了大神的blog之后总结一下其中的用法,方便以后在工作中使用()
一、老版动画
老版动画主要集中在android.view.animation中,如果需要在xml文件中使用,需要在res下新建anim文件夹
老版的动画分为逐帧动画和补间动画
①逐帧动画
就是一个图片一个图片的播放,可以设置每个图片的停留时间之类的,一般直接用xml来实现,这里是从(http://www.jianshu.com/p/420629118c10)copy的一小段逐帧代码,需要在drawable文件夹下新建
在Activity使用如下
ImageView animationImg1 = (ImageView) findViewById(R.id.animation1);
animationImg1.setImageResource(R.drawable.frame_anim1);
AnimationDrawable animationDrawable1 = (AnimationDrawable) animationImg1.getDrawable();
animationDrawable1.start();
②补间动画
补间动画分为alpha、translate、scale、rotate,分别是透明度、位移、缩放、旋转
如需要某个图片放大一点的动画
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="1.0"
android:toXScale="1.5"
android:fromYScale="1.0"
android:toYScale="1.5"
android:pivotX="50%"
android:pivotY="50%" />
fromXScale:float,起始的X方向上相对自身的比例,如2.0 即放大一倍
pivoX:起点的X轴坐标,如:50 原点处加上50px,50% 原点处加上自身宽度的百分之五十,50%p 原点处加上父控件宽度的百分之五十
如果想要在代码中使用
Animation animation = AnimationUtils.loadAnimation(mContext, R.anim.scale_anim);
img = (ImageView) findViewById(R.id.img);
img.startAnimation(animation);
若是想直接在代码中动态使用,再设置如重复次数、是否在动画结束后停留在执行完的状态
RotateAnimation rotate = new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotate.setRepeatMode(3);
rotate.setFillAfter(true);
若是需要动画混合使用的话,可以使用AnimationSet,该类也是继承自Animation
?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<scale android:fromXScale="1"
android:toXScale="1.2"
android:fromYScale="1"
android:toYScale="1.2"
android:pivotX="50%"
android:pivotY="50%"/>
<alpha
android:fromAlpha="0"
android:toAlpha="1"/>
</set>
上面的代码就是在放大的同时,从透明到完全不透明的效果,至于xml文件如何在代码中使用,与上面的补间动画相同即可。
若需要在代码中动态使用AnimationSet,通过add方法添加补间动画即可,至于构造函数中的true,即为添加的所有补间动画是否共享AnimationSet设置的interpolator
AnimationSet animationSet1 = new AnimationSet(true);
animationSet1.addAnimation(rotate);
二、属性动画
优点:可以对非View进行操作、实现非补间动画类型之外的动画、真正的改变属性
主要是来自于android.animation包中
主要有ValueAnimator与ObjectAnimator,其中后者继承了前者
①ValueAnimator
主要是对值进行改变
如下面的代码
ValueAnimator animator = ValueAnimator.ofFloat(1f,5f,3f);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
float currentValue = (Float) valueAnimator.getAnimatedValue();
Log.i("wzt","currentValue = " + currentValue);
invalidate();
}
});
打印出的currentValue应该是从1变化到5再变化到3的
我们可以通过实现一个TypeEvaluation接口,来告诉ValueAnimation如何去改变一个对象对应的值
如下,Point是我们自己创建的一个类,里面有x,y用于存储位置的信息
public class PointeEvaluator implements TypeEvaluator {
@Override
public Object evaluate(float v, Object o, Object t1) {
Point startpoint = (Point) o;
Point endpoint = (Point) t1;
float startx = startpoint.getX();
float starty = startpoint.getY();
float endx = endpoint.getX();
float endy = endpoint.getY();
float currentx = startx + (v * (endx - startx));
float currenty = starty + (v * (endy - starty));
return new Point(currentx,currenty);
}
}
可以声明ValueAnimator的时候,就可以在ofObject中使用了
接着通过在onAnimationUpdate中得到相应的对象,在自定义view里就可以根据得到的对象去绘图
ValueAnimator animator = ValueAnimator.ofObject(new PointeEvaluator(),new Point(RADIUS,RADIUS),new Point(getWidth()-RADIUS,getHeight()-RADIUS));
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
currentPoint = (Point) valueAnimator.getAnimatedValue();
invalidate();
}
});
②ObjectAnimator
如果以后在工作中需要用到动画的话,可能这会是使用最多的一个类,因为用起来相对于前面来说太方便了
它可以直接对任意对象的属性进行操作,如View的alpha属性
xml中的使用方式
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="5000"
android:valueType="floatType"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"/>
若是使用AnimatorSet进行混合的话,xml如下,注意ordering表示该set内的子项是同时播放还是顺序播放。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:propertyName="rotation"
android:valueType="floatType"
android:valueFrom="0f"
android:valueTo="360f"
android:duration="1000"/>
<set android:ordering="sequentially">
<objectAnimator
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="1f"
android:valueTo="0f"
android:duration="500"/>
<objectAnimator
android:propertyName="alpha"
android:valueType="floatType"
android:valueFrom="0f"
android:valueTo="1f"
android:duration="500"/>
</set>
</set>
使用时
ObjectAnimator temp = (ObjectAnimator) AnimatorInflater.loadAnimator(this,R.animator.object_animator);
Animator animator = AnimatorInflater.loadAnimator(this,R.animator.animator_mix);
animator.setTarget(imageView);
若是直接在java中动态使用
ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(imageView,"alpha",1f,0f,1f);
ObjectAnimator rolateAnimator = ObjectAnimator.ofFloat(imageView,"rotation",0f,360f);
AnimatorSet animationSet = new AnimatorSet();
animationSet.setDuration(1000);
animationSet.play(alphaAnimator).with(rolateAnimator);
animationSet.start();
上面的代码中AnimatorSet.play返回了一个AnimatorSet.Builder的实例,包括了下面几种方法
after 将一个动画放到之后执行
after(int)延迟执行
before 将一个动画放到动画之前执行
with 将这个动画一起执行
因此上面代码的逻辑就是alphaAnimator与rolateAnimator一起执行了
注意ObjectAnimator中如果需要修改其他属性的话,如Color,可以直接在View中新增Color的getter与setter,之后就可以通过如下一条代码使用了
ObjectAnimator anim = ObjectAnimator.ofObject(myAnimView, "color", new ColorEvaluator(),
"#0000FF", "#FF0000");
三、Interpolation
控制动画的变化速率,从而实现一种非线性的动画效果
主要就是通过实现Interpolator接口来实现,其中的getInterpolation里的v属性就是从0~1的一个变化过程
如下代码就是实现大小从0~1.2之后,再回到1的效果
public class MyInterpolator implements Interpolator {
@Override
public float getInterpolation(float v) {
if (v < 0.8) {
return (float) (v * 1.5 / 0.8);
} else {
return (float) (1.5 - v * 0.2);
}
}
}
其余还有很多系统自带的
如BounceInterpolator是模拟反弹的效果
textview.animate().x(500).y(500).setDuration(5000)
.setInterpolator(new BounceInterpolator());
extview.animate().alpha(0f);
调用之后会直接启动动画的播放
以上就是关于安卓动画的一个小总结,最近才开始写blog,真是好麻烦=。= 希望能保持这样的习惯