Android动画学习

参考:Android 动画总结——View 动画、属性动画、帧动画

一、VIew动画

View动画定义了渐变Alpha、旋转Rotate、缩放Scale、平移Translate四种基本动画,可用XML文件定义,也可用Java代码实现。

1. Xml文件定义动画

利用xml文件定义View动画需要在工程的res目录下创建anim文件夹,所有的xml定义的View动画都要放在anim目录下。

1)公有属性

android:duration     动画持续时间
android:fillAfter    为true动画结束时,View将保持动画结束时的状态
android:fillBefore   为true动画结束时,View将还原到开始开始时的状态
android:repeatCount  动画重复执行的次数
android:repeatMode   动画重复模式 ,重复播放时restart重头开始,reverse重复播放时倒叙回放,该属性需要和android:repeatCount一起使用
android:interpolator 插值器,相当于变速器,改变动画的不同阶段的执行速度

2)渐变alpha

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

3)旋转rotate

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fillAfter="true"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360">
</rotate>

4)缩放scale

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="2000"
       android:fromXScale="1.0"
       android:fromYScale="1.0"
       android:pivotX="50%"
       android:pivotY="50%"
       android:toXScale="0.5"
       android:toYScale="0.5">
</scale>

5)平移tanslate

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

6)在Activity中使用

public void clickToAlpha(View view) {
    Animation alphaAnim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.view_anim_alpha);
    mTargetView.startAnimation(alphaAnim);
}
2. Java代码实现VIew动画

1)渐变

public void clickToAlpha(View view) {
    AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
    alphaAnimation.setDuration(2000);
    mTargetView.startAnimation(alphaAnimation);
}

2)旋转

public void clickToRotate(View view) {
    RotateAnimation rotateAnimation = new RotateAnimation(
            0, 360,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f);
    rotateAnimation.setDuration(2000);
    mTargetView.startAnimation(rotateAnimation);
}

3)缩放

public void clickToScale(View view) {
    ScaleAnimation scaleAnimation = new ScaleAnimation(
            1, 0.5f,
            1, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f);
    scaleAnimation.setDuration(2000);
    mTargetView.startAnimation(scaleAnimation);
}

4)平移

public void clickToTranslate(View view) {
    TranslateAnimation translateAnimation = new TranslateAnimation(
            Animation.RELATIVE_TO_SELF, 0,
            Animation.RELATIVE_TO_SELF, 1,
            Animation.RELATIVE_TO_SELF, 0,
            Animation.RELATIVE_TO_SELF, 1);
    translateAnimation.setDuration(2000);
    mTargetView.startAnimation(translateAnimation);
}

5)组合

public void clickToSet(View view) {
    AnimationSet animationSet = new AnimationSet(true);
    animationSet.addAnimation(alphaAnimation);
    animationSet.addAnimation(rotateAnimation);
    animationSet.addAnimation(scaleAnimation);
    animationSet.addAnimation(translateAnimation);

    mTargetView.startAnimation(animationSet);
}
3. 动画监听
animation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
        // 动画开始
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        // 动画结束
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
        //动画重复
    }
});
4. 动画销毁
protected static void stopAnimation() {
        mTargetView.clearAnimation();
        if (animationSet != null) {
            // 取消动画
            animationSet.cancel();
            // 释放资源
            animationSet.reset();
            animationSet = null;
        }
    }

二、属性动画

所谓属性动画,就是改变对象Object的属性来实现动画过程。属性动画是对View的动画的扩展,通过它可以实现更多漂亮的动画效果。同时属性动画的作用对象不仅仅是View,任何对象都可以。
属性动画的作用效果就是:在一个指定的时间段内将对象的一个属性的属性值动态地变化到另一个属性值。

1. ObjectAnimator

1)Java代码实现

ObjectAnimtor可以用ofInt、ofFloat、ofObject等静态方法,传入动画作用的目标Object、属性字段、属性开始值、属性中间值、属性结束值等参数来构造动画对象。
在动画更新的过程中,通过不断去调用对象属性的setter方法改变属性值,不断重绘实现动画过程。如果没有给定动画开始属性值,那么系统会通过反射去获取Object对象的初始值作为动画的开始值。

private void startJavaPropertyAnimator() {
    ObjectAnimator
            .ofFloat(mImageView, "rotationY", 0f, 360f)
            .setDuration(2000)
            .start();
}

上面的代码就是通过ObjectAnimator在2000ms内将mImageView的rotationY属性的属性值从0f变化的360f。

2)XML文件定义

属性动画也同样可以通过xml文件来定义,同样在工程的res目录下创建animator文件夹,xml文件定义的objectAnimator动画要放在该文件夹下。

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
                android:duration="2000"
                android:propertyName="rotationY"
                android:valueFrom="0"
                android:valueTo="360"
                android:valueType="floatType">
</objectAnimator>

private void startXmlPropertyAnimator() {
    Animator animator = AnimatorInflater.loadAnimator(getApplicationContext(), 
    R.animator.property_animator);
    animator.setTarget(mImageView);
    animator.start();
}

3)组合使用

属性动画也同样可以组合使用,通过AnimatorSet类和xml文件的set标签都可以同时改变对象的多个属性,实现更加丰富的动画效果。

private void startJavaPropertyAnimatorSet() {
    Animator scaleXAnimator = ObjectAnimator.ofFloat(mImageView, "scaleX", 1, 0.5f);
    scaleXAnimator.setDuration(2000);
    Animator scaleYAnimator = ObjectAnimator.ofFloat(mImageView, "scaleY", 1, 0.5f);
    scaleYAnimator.setDuration(2000);
    Animator rotationXAnimator = ObjectAnimator.ofFloat(mImageView, "rotationX", 0, 360);
    rotationXAnimator.setDuration(2000);
    Animator rotationYAnimator = ObjectAnimator.ofFloat(mImageView, "rotationY", 0, 360);
    rotationYAnimator.setDuration(2000);
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.play(scaleXAnimator)
            .with(scaleYAnimator)
            .before(rotationXAnimator)
            .after(rotationYAnimator);
    animatorSet.start();
}

AnimatorSet通过before、with、after三个方法可以组合多个属性动画,with表示与给定动画同时执行,before在给定动画执行之前执行,after表示在给定动画执行之后执行。

4)动画监听

animator.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) {
        // 动画重复
    }
});
2. ValueAnimator

ValueAnimator是ObjectAnimator的父类,它继承自Animator。ValueAnimaotor同样提供了ofInt、ofFloat、ofObject等静态方法,传入的参数是动画过程的开始值、中间值、结束值来构造动画对象。可以将ValueAnimator看着一个值变化器,即在给定的时间内将一个目标值从给定的开始值变化到给定的结束值。在使用ValueAnimator时通常需要添加一个动画更新的监听器,在监听器中能够获取到执行过程中的每一个动画值。

private void startValueAnimator() {
    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
    valueAnimator.setDuration(300);
    valueAnimator.start();
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            // 动画更新过程中的动画值,可以根据动画值的变化来关联对象的属性,实现属性动画
            float value = (float) animation.getAnimatedValue();
            Log.d("ValueAnimator", "动画值:" + value);
        }
    });
}

ValueAnimator的使用一般会结合更新监听器AnimatorUpdateListener,大多数时候是在自定义控件时使用。

3. TypeEvalutaor

ObjectAnimator和ValueAnimator都有ofObject方法,传入的都有一个TypeEvaluator类型的参数。TypeEvaluator是一个接口。

(待学习)

三、帧动画

帧动画需要开发者制定好动画每一帧,系统一帧一帧的播放图片。

1. Java实现
private void start1() {
    AnimationDrawable ad = new AnimationDrawable();
    for (int i = 0; i < 7; i++) {
        Drawable drawable = getResources().getDrawable(getResources().getIdentifier("ic_fingerprint_" + i, "drawable", getPackageName()));
        ad.addFrame(drawable, 100);
    }
    ad.setOneShot(false);
    mImageView.setImageDrawable(ad);
    ad.start();
}
2. XML定义
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
<item android:drawable="@drawable/ic_fingerprint_0" android:duration="100"/>
<item android:drawable="@drawable/ic_fingerprint_1" android:duration="100"/>
<item android:drawable="@drawable/ic_fingerprint_2" android:duration="100"/>
<item android:drawable="@drawable/ic_fingerprint_3" android:duration="100"/>
<item android:drawable="@drawable/ic_fingerprint_4" android:duration="100"/>
<item android:drawable="@drawable/ic_fingerprint_5" android:duration="100"/>
<item android:drawable="@drawable/ic_fingerprint_6" android:duration="100"/>
</animation-list>

private void start2() {
    mImageView.setImageResource(R.drawable.frame_anim);
    AnimationDrawable animationDrawable = (AnimationDrawable) mImageView.getDrawable();
    animationDrawable.start();
}

其中android:onshot属性和setOneShot方法表示是否只执行一次。
AnimationDrawable实际是上是一个Drawable动画,动画执行的过程总会给你不断重绘Drawable的每一帧图像,实现动态播放效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值