安卓动画之补间动画(Tween Animations)

Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果(旋转、平移、放缩和渐变)

使用动画来进行旋转、平移、放缩和渐变比通过手动重新绘制Canvas来达到相似效果要消耗更少的资源,实现更简单

1.创建补间动画

AlphaAnimation

java:

Animation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);  
alphaAnimation.setDuration(3000);  
this.startAnimation(alphaAnimation); 

其中AlphaAnimation类第一个参数fromAlpha表示动画起始时的透明度, 第二个参数toAlpha表示动画结束时的透明度。

setDuration用来设置动画持续时间。

xml:

<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android">  
    <alpha  
        android:fromAlpha="0.1"  
        android:toAlpha="1.0"  
        android:duration="2000"  
    />  
</set> 

RotateAnimation

java:

Animation rotateAnimation = new RotateAnimation(0f, 360f);  
rotateAnimation.setDuration(1000);  
this.startAnimation(rotateAnimation);

其中RotateAnimation类第一个参数fromDegrees表示动画起始时的角度, 第二个参数toDegrees表示动画结束时的角度。 

另外还可以设置伸缩模式pivotXType、pivotYType, 伸缩动画相对于x,y 坐标的开始位置pivotXValue、pivotYValue等。

xml:

<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android">  
    <rotate  
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
        android:fromDegrees="0"  
        android:toDegrees="360"  
        android:pivotX="50%"  
        android:pivotY="50%"  
        android:duration="500"  
    />  
</set>

ScaleAnimation

java:

Animation scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f);  
scaleAnimation.setDuration(500);  
this.startAnimation(scaleAnimation); 

第一个参数fromX ,第二个参数toX:分别是动画起始、结束时X坐标上的伸缩尺寸。

第三个参数fromY ,第四个参数toY:分别是动画起始、结束时Y坐标上的伸缩尺寸。

另外还可以设置伸缩模式pivotXType、pivotYType, 伸缩动画相对于x,y 坐标的开始位置pivotXValue、pivotYValue等。

xml:

<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android">  
    <scale  
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
        android:fromXScale="0.0"  
        android:toXScale="1.0"  
        android:fromYScale="0.0"  
        android:toYScale="1.0"  
        android:pivotX="50%"  
        android:pivotY="50%"  
        android:fillAfter="false"  
        android:duration="500"
        android:startOffset="700"
        android:repeatCount="10"
    />     
</set>

TranslateAnimation

java:

Animation translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f);  
translateAnimation.setDuration(1000);  
this.startAnimation(translateAnimation);  

第一个参数fromXDelta ,第二个参数toXDelta:分别是动画起始、结束时X坐标。

第三个参数fromYDelta ,第四个参数toYDelta:分别是动画起始、结束时Y坐标。

xml:

<?xml version="1.0" encoding="utf-8"?>  
<set xmlns:android="http://schemas.android.com/apk/res/android">  
    <translate  
        android:fromXDelta="10"  
        android:toXDelta="100"  
        android:fromYDelta="10"  
        android:toYDelta="100"  
    />  
</set>

AnimationSet

java:

translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f);  
alphaAnimation = new AlphaAnimation(0.1f, 1.0f);   
AnimationSet set = new AnimationSet(true);  
set.addAnimation(translateAnimation);  
set.addAnimation(alphaAnimation);  
set.setDuration(1000);  
this.startAnimation(set);
xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="300"
        android:fromYDelta="100"
        android:toYDelta="0" />
    透明度渐变
    <alpha
        android:duration="300"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />
    <scale
        android:duration="300"
        android:fillAfter="false"
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0" >
    </scale>
</set>

2.使用补间动画

动画资源存放在项目的res/anim文件夹下

如何来使用这些xml文件呢?其实也很简单,此时需要用到AnimationUtils类。 通过该类中 loadAnimation 方法来加载这些布局文件。

Animation anim = AnimationUtils.loadAnimation(this.getContext(), R.anim.alpha_anim);
调用View的startAnimation方法,动画序列只会运行一次,然后停止。但是可以使用动画或动画集的setRepeatMode和setRepeatCount修改这种行为。
 
 
 
 
animation.setRepeatMode(Animation.REVERSE);  
animation.setRepeatCount(Animation.INFINITE);
view.startAnimation(animation);
 
 3.使用动画监听器 
 

动画还可以添加监听事件,监听到动画的开始,结束和重复

mAnimationSet.setAnimationListener(new AnimationListener() {		
			@Override
			public void onAnimationStart(Animation animation) {
				// TODO Auto-generated method stub
			}
			
			@Override
			public void onAnimationRepeat(Animation animation) {
				// TODO Auto-generated method stub
			}
			
			@Override
			public void onAnimationEnd(Animation animation) {
				// TODO Auto-generated method stub
			}
		});

3.为布局和View Group添加动画

LayoutAnimation

LayoutAnimation可以来为viewGroup添加动画,并按照顺序把一个动画应用到viewGroup中的每一个子View上

xml:

<layoutAnimation  xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/more_in"
    android:aninationOrder="random"
    android:delay="30%"/>

animationOrder,这个是说子view按照什么顺序来执行anim,可以使normal(正常,0-n),reverse(反序,n-0),random(随机)

delay,用于延迟的每个子view的动画开始动画持续时间的浮点数。越大间隔越长。0.3或者30%的字样。

使用动画是直接在viewGroup布局定义中使用android:LayoutAnimation来完成的

android:layoutAnimation="@anim/layout_more_in"
java:
在java中使用 LayoutAnimation要借助LayoutAnimationController

LinearLayout ll = (LinearLayout) findViewById(R.id.ll);  
ScaleAnimation sa = new ScaleAnimation(0, 1, 0, 1);  
sa.setDuration(2000);  
// 第二个参数dely : the delay by which each child's animation must be offset  
LayoutAnimationController lac = new LayoutAnimationController(sa, 0.5F);  
// 设置显示的顺序 这个必须要在dely不为0的时候才有效  
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);  
ll.setLayoutAnimation(lac);

通常情况下,布局动画会在viewGroup第一次进行布局的时候执行一次,可以通过对viewGroup对象调用scheduleLayoutAnimation强制它再次执行,当viewGroup在下次布局的时候,这个动画会再次执行

viewGroup.scheduleLayoutAnimation();

LayoutTransition

public class AnimateLayoutTransition extends Activity {  
  
    private LinearLayout ll;  
    private LayoutTransition mTransition = new LayoutTransition();  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.animate_layout_transition);  
  
        ll = (LinearLayout) findViewById(R.id.ll);  
        setupCustomAnimations();  
        ll.setLayoutTransition(mTransition);  
    }  
  
    public void add(View view) {  
        final Button button = new Button(this);  
        ll.addView(button);  
        button.setOnClickListener(new OnClickListener() {  
  
            @Override  
            public void onClick(View arg0) {  
                ll.removeView(button);  
            }  
        });  
    }  
  
    // 生成自定义动画  
    private void setupCustomAnimations() {  
        // 动画:CHANGE_APPEARING  
        // Changing while Adding  
        PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1);  
        PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 1);  
        PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", 0, 1);  
        PropertyValuesHolder pvhBottom = PropertyValuesHolder.ofInt("bottom", 0, 1);  
        PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f);  
        PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f);  
  
        final ObjectAnimator changeIn = ObjectAnimator.ofPropertyValuesHolder(  
                this, pvhLeft, pvhTop, pvhRight, pvhBottom, pvhScaleX,  
                pvhScaleY).setDuration(  
                mTransition.getDuration(LayoutTransition.CHANGE_APPEARING));  
        mTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, changeIn);  
        changeIn.addListener(new AnimatorListenerAdapter() {  
            public void onAnimationEnd(Animator anim) {  
                View view = (View) ((ObjectAnimator) anim).getTarget();  
                // View也支持此种动画执行方式了  
                view.setScaleX(1f);  
                view.setScaleY(1f);  
            }  
        });  
  
        // 动画:CHANGE_DISAPPEARING  
        // Changing while Removing  
        Keyframe kf0 = Keyframe.ofFloat(0f, 0f);  
        Keyframe kf1 = Keyframe.ofFloat(0.5f, 360f);  
        Keyframe kf2 = Keyframe.ofFloat(1f, 0f);  
        PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);  
        final ObjectAnimator changeOut = ObjectAnimator.ofPropertyValuesHolder(this, pvhRotation)  
                .setDuration(mTransition .getDuration(LayoutTransition.CHANGE_DISAPPEARING));  
        mTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeOut);  
        changeOut.addListener(new AnimatorListenerAdapter() {  
            public void onAnimationEnd(Animator anim) {  
                View view = (View) ((ObjectAnimator) anim).getTarget();  
                view.setRotation(0f);  
            }  
        });  
  
        // 动画:APPEARING  
        // Adding  
        ObjectAnimator animIn = ObjectAnimator.ofFloat(null, "rotationY", 90f, 0f).setDuration(  
                mTransition.getDuration(LayoutTransition.APPEARING));  
        mTransition.setAnimator(LayoutTransition.APPEARING, animIn);  
        animIn.addListener(new AnimatorListenerAdapter() {  
            public void onAnimationEnd(Animator anim) {  
                View view = (View) ((ObjectAnimator) anim).getTarget();  
                view.setRotationY(0f);  
            }  
        });  
  
        // 动画:DISAPPEARING  
        // Removing  
        ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotationX", 0f, 90f).setDuration(  
                mTransition.getDuration(LayoutTransition.DISAPPEARING));  
        mTransition.setAnimator(LayoutTransition.DISAPPEARING, animOut);  
        animOut.addListener(new AnimatorListenerAdapter() {  
            public void onAnimationEnd(Animator anim) {  
                View view = (View) ((ObjectAnimator) anim).getTarget();  
                view.setRotationX(0f);  
            }  
        });  
  
    }  
}  


过渡的类型一共有四种:
LayoutTransition.APPEARING 当一个View在ViewGroup中出现时,对此View设置的动画
LayoutTransition.CHANGE_APPEARING当一个View在ViewGroup中出现时,此View对其他View位置造成影响,对其他View设置的动画
LayoutTransition.DISAPPEARING当一个View在ViewGroup中消失时,对此View设置的动画
LayoutTransition.CHANGE_DISAPPEARING当一个View在ViewGroup中消失时,此View对其他View位置造成影响,对其他View设置的动画
LayoutTransition.CHANGE 不是由于View出现或消失造成对其他View位置造成影响,然后对其他View设置的动画。
注意动画到底设置在谁身上,此View还是其他View。

AnimateLayoutChanges

ViewGroup的xml属性中有一个默认的animateLayoutChanges属性,设置该属性,可以添加ViewGroup增加view的过渡效果:
<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
android:id="@+id/ll"  
android:layout_width="match_parent"  
android:layout_height="match_parent"  
android:animateLayoutChanges="true"  
android:orientation="vertical" >  
<Button  
android:id="@+id/button1"  
android:layout_width="wrap_content"  
android:layout_height="wrap_content"  
android:onClick="add"  
android:text="Add Button" />  
</LinearLayout>



你可能感兴趣的:(安卓动画之补间动画(Tween Animations))