提供了AlphaAnimation, RotateAnimation, TranslateAnimation, ScaleAnimation四种动画方式
*透明度
AlphaAnimation aa = new AlphaAnimation(0,1); //透明度0到1
aa.setDuration(1000);
view.setAnimation(aa);
*旋转
RotateAnimation ra = new RotateAnimation(0,360,100,100); //旋转的始终角度和旋转中心
ra.setDuration(1000);
view.setAnimation(ra);
通过参数控制动画的参考系
RotateAnimation ra = new RotateAnimation(0,360,RotateAnimaiton.RELATIVE_TO_SELF,0.5F,RELATIVE_TO_SELF,0.5F);//以自身为参考系
*位移动画
TranslateAnimation ta = new TranslateAnimation(0,200,0,300);
ta.setDuration(1000);
view.setAnimation(ta);
*缩放动画
ScaleAnimation sa = new ScaleAnimation(0,2,0,2);
//ScaleAnimation sa = new ScaleAnimation(0,2,0,2,Animation.RELATIVE_TO_SELF,0.5F,Animation.RELATIVE_TO_SELF,0.5F);
sa.setDuration(1000);
view.setAnimation(sa);
AnimationSet
将动画以组合的形式展现出来
AnimationSet as = new AnimationSet(true);
as.setDuration(1000);
...
as.addAnimation(aa);
as.addAnimation(ta);
as.addAnimation(sa);
as.addAnimation(ra);
view.startAnimation(as);
*动画的监听回调
animation.setAnimationListener(new Animation.AnimationListener(){
@override
public void onAnimationStart(Animation animation){}
@override
public void onAnimationEnd(Animation animation){}
@override
public void onAnimationRepeat(Animation animation){}
});
AnimatorSet 和 ObjectAnimator配合,前者进行更精细化的控制,能够自由驱动,可以调用setFrameDelay(longframeDelay)设置动画帧之间的间隔时间,后者进行组合。
属性动画通过调用属性的set get方法来真实控制一个View的属性。
*ObjectAnimator
创建一个ObjectAnimator对象只需要通过他的静态工厂方法直接返回,参数包括一个对象和对象的属性名,但这个属性必须有set get方法。
ObjectAnimator animator = ObjectAnimator.ofFloat(
view,
"translationX",
300);
animator.setDuration(300);
animator.start();
常用的可以直接使用的属性:
**translationX和translationY:布局容器左上角的偏移值
**rotation, rotationX, rotationY:围绕支点进行2D和3D旋转
**scaleX, scaleY:围绕支点进行2D缩放
**pivotX, pivotY:支点。默认是View对象的中心
**x, y:在容器中的最终位置,是最初的左上角坐标和tX tY值的累积和
**alpha:透明度,默认1(完全不透明)
如果一个属性没有set get方法,有两种解决方法,一是使用包装类,二是通过ValueAnimator来实现
**包装类解决方法
private static class WrapperView{
public View mTarget;
public WrapperView (View target){
mTarget = target;
}
public int getWidth(){
return mTarget.getLayoutParams().width;
}
public void setWidth(int width){
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
}
ViewWrapper wrapper = new ViewWrapper(mButton);
ObjectAnimator.ofInt(wrapper,"width",500).setDuration(5000).start();
**ValueAnimator
本身不提供任何动画效果,更像一个数值发生器,用来产生具有一定规律的数字
ValueAnimator animator = ValueAnimator.ofFloat(0,100);
animator.setTarget(view);
animator.setDuration(1000).start();
animator.addUpdateListener(new AnimatorUpdateListener(){
@Override
public void onAnimationUpdate(ValueAniamtor animation){
Float value = (Float)animation.getAnimatedValue();
//TODO use the value
}
});
通常情况下,在ValueAnimator的AnimatorUpdateListener中监听数值的变换,从而完成动画的变化。
*PropertyValueHolder
实现对于一个对象的多个属性的控制
PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", 300f);
PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX", 1f,0,1f);
PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY", 1f,0,1f);
ObjectAnimator.ofPropertyValuesHolder(view, pvh1, pvh2, pvh3).setDuration(1000).start();
*动画时间的监听
ObjectAnimator anim = ObjectAnimator.ofFloat(view,"alpha", 0.5f);
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
大部分时间我们只关心onAnimationEnd事件:
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
}
});
*AnimatorSet
实现对多个属性的控制,同时还能实现更为精确的顺序控制
ObjectAnimator animator1 = ObjectAnimator.ofFloat(view,"translationX",300f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(view,"scaleX",1f,0f,1f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(view,"scaleY",1f,0f,1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(animator1,animator2,animator3);
set.start();
在属性动画中,通过playTogether(),playSequentially(),animSet.play().with()/before()/after()这些方法来控制多个动画的协同工作
*在XML中使用
public void scale(View view){
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scaleX);
anim.setTarget(mMv);
anim.start();
}
*View的animate方法
可以直接驱动属性动画
view.animate()
.alpha(0)
.y(300)
.setDuration(300)
.withStartAciton(new Runnable(){
@overrid
public void run(){}
})
.withEndAciton(new Runnable(){
@overrid
public void run(){
runOnUiThread(new Runnable(){
@overrid
public void run(){}
})
}
})
.start();
-->布局动画