参考
属性动画
Android源码分析—属性动画的工作原理
一、view动画
- TranslateAnimation
- ScaleAnimation
- RotateAnimation
- AlphaAnimation
建议使用XML来定义动画,可读性比较好
//res/anim/animation_test.xml
...
如何应用上面的动画呢
Button mButton = (Button)findViewById(R.id.buttton1);
Animation animation = AnimationUtils.
loadAnimation(this,R.anim.animation_test);
mButton.startAnimation(animation);
- view动画只能控制view对象
- view动画只有平移缩放旋转淡入淡出效果
- view动画只是对影像做动画 交互事件容易出问题
二、帧动画
使用AnimationDrawable。帧动画容易引起OOM,尽量避免使用过多尺寸较大的图片
//res/drawable/frame_animation.xml
...
...
Button mButton = (Button)findViewById(R.id.button1);
mButton.setBackgroundResource(R.drawable.frame_animation);
AnimationDrawable drawable = (AnimationDrawable) mButton.getBackground();
drawable.start();
三、属性动画
android3.0,api11之后才有属性动画。默认帧率10ms/帧,动画默认时间间隔300ms。
- ValueAnimator
//三秒内颜色渐变,无限循环且反复
ValueAnimator colorAnim = ObjectAnimator.ofInt(this,
"backgroundColor",/\*Red\*/0xffff8080,/\*Blue\*/0xff8080ff);
colorAnim.setDuration(3000);
colorAnim.setEvaluator(new ArgbEvaluator());
colorAnim.setRepeatCount(ValueAnimator.INFINITE);
colorAnim.setRepeatMode(ValueAnimator.REVERSE);
colorAnim.start();
//测试数值0到1的变化
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.d("TAG", "cuurent value is " + currentValue);
}
});
anim.start();
- 继承自ValueAnimator的ObjectAnimator
ObjectAnimator.ofFloat(myObject,"translationY",
-myObject.getHeight()).start();//向上平移他的高度
- AnimatorSet 动画集合
5秒内对view的旋转、平移、缩放和透明度都进行了改变。
AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(myView,"rotationX",0,360),
ObjectAnimator.ofFloat(myView,"rotationY",0,180),
ObjectAnimator.ofFloat(myView,"rotation",0,-90),
ObjectAnimator.ofFloat(myView,"translationX",0,90),
ObjectAnimator.ofFloat(myView,"translationY",0,90),
ObjectAnimator.ofFloat(myView,"scaleX",1,1.5f),
ObjectAnimator.ofFloat(myView,"scaleY",1,1.5f),
ObjectAnimator.ofFloat(myView,"alpha",1,0.25f,1)
);
set.setDuration(5*1000).start();
四、让一个Button宽度从当前宽度增加到500px
- 方式一:使用view动画,拉伸的只是影像,背景图和文字都会变形。
- 方式二:
public void onClick(View v){
if(v == Button){
performAnimate();
}
}
private void performAnimate(){
ObjectAnimator.ofInt(mButton,"width",500).setDuration(5000).start();
}
这样是无效的,object会不停地调用set方法,但是button的setWidth由于继承自TextView,其设置的是最大宽度和最小宽度,真正起作用的是width. - 方式三:
将方式二包装一下
private static class ViewWrapper{
private View mTarget;
public ViewWrapper(View target){
mTarget = target;
}
public int getWidth(){
return mTarget.getLayoutParams().width;
}
public void setWidth(int width){
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
private void performAnimate(){
ViewWrapper wrapper = new ViewWrapper(mButton);
ObjectAnimator.ofInt(wrapper,"width",500).setDuration(5000).start();
}
}
- 方式四:
使用ValueAnimator
private void performAnimate(final View target,final int start,final int end){
ValueAnimator valueAnimator = ValueAnimator.ofInt(1,100);//动画过程中从1变成100
valueAnimator.addUpdateListener(
new AnimatorUpdateListener(){
//持有一个IntEvaluator对象,方便下面估值时使用
private IntEvalluator mEvaluaotr = new IntEvalluator();
public void onAnimationUpdate(ValueAnimator animation){
int currentValue = (Integer)animator.getAnimatedValue();//1~100间
float fraction = animator.getAnimatedFraction();//当前进度,0~1间
target.getLayoutParams().width = mEvaluaotr.
evaluate(fraction,start,end);
target.requestLayout();
}
}
);
valueAnimator.setDuration(5000).start();
}
performAnimate(mButton,mButton.getWidth(),500);