android动画总结

android动画总结

android动画大致可以分为两类,一类是通过播放多张图片的帧动画,另一类就是通过设置和修改控件属性达到动画的目的。

帧动画

1、通过xml文件设置帧动画

<animation-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@drawable/run1"
        android:duration="100"/>
    <item
        android:drawable="@drawable/run2"
        android:duration="100"/>
    <item
        android:drawable="@drawable/run3"
        android:duration="100"/>
    <item
        android:drawable="@drawable/run4"
        android:duration="100"/>
    <item
        android:drawable="@drawable/run5"
        android:duration="100"/>
    <item
        android:drawable="@drawable/run6"
        android:duration="100"/>
    <item
        android:drawable="@drawable/run7"
        android:duration="100"/>
</animation-list>

2.通过代码设置帧动画:

    AnimationDrawable animationDrawable = new AnimationDrawable();
    for (int i = 1; i < 8; i++) {
        int id = getResources().getIdentifier("run" + i, "drawable", getPackageName());
        Drawable drawable = getDrawable(id);
        if (null != drawable) {
            animationDrawable.addFrame(drawable, 100);
        }
    }

3.启动和结束动画:

1、xml形式
    AnimationDrawable animationDrawable = (AnimationDrawable) target.getDrawable();
2、代码形式:
    target.setImageDrawable(animationDrawable);
3、开始/停止动画    
    target.start();/target.stop();

属性动画

属性动画主要围绕几个属性进行,旋转、平移、缩放、透明度,通过设置初始值和最终值根据给定的时间和加速曲线进行,xml展现如下:

<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:interpolator="@android:anim/linear_interpolator"
     android:shareInterpolator="true">
    <alpha
        android:duration="2000"
        android:fillAfter="true"
        android:fillBefore="false"
        android:fromAlpha="1.0"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:toAlpha="0.0"/>
    <rotate
        android:duration="2000"
        android:fillAfter="true"
        android:fillBefore="false"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:toDegrees="360"/>
    <set
        android:interpolator="@android:anim/bounce_interpolator"
        android:shareInterpolator="true"
        android:startOffset="1000">
        <scale
            android:duration="2000"
            android:fillAfter="true"
            android:fillBefore="false"
            android:fromXScale="1.0"
            android:fromYScale="1.0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:repeatCount="2"
            android:repeatMode="reverse"
            android:toXScale="2.0"
            android:toYScale="2.0"/>
        <translate
            android:duration="2000"
            android:fillAfter="true"
            android:fillBefore="false"
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:repeatCount="2"
            android:repeatMode="reverse"
            android:toXDelta="200%"
            android:toYDelta="200%"/>
    </set>
</set>

fromXDelta: X轴方向开始位置,可以是%,也可以是具体的像素
fromYDelta: Y轴方向开始位置,可以是%,也可以是具体的像素
toXDelta:X轴方向结束位置,可以是%,也可以是具体的像素
toYDelta:Y轴方向结束位置,可以是%,也可以是具体的像素
pivotX:表示缩放/旋转起点 X 轴坐标,可以是整数值、百分数(或者小数)、百分数p三种样式,比如 50、50% / 0.5、50%p。当属性值为数值时,表示在当前 View 的左上角,即原点处加上 50px,作为起始点;如果是百分数,比如 50%,表示在当前控件的左上角加上自己宽度的 50% (即自身宽度中心)作为起始点;如果是 50%p(字母 p 是 parent 的意思),取值的基数是父控件,那么 50%p 就是表示在当前的左上角加上父控件宽度的 50% 作为起始点 x 轴坐标。
pivotY:参考pivotX

加速器如下:

@android:anim/accelerate_interpolator: 越来越快

@android:anim/decelerate_interpolator:越来越慢

@android:anim/accelerate_decelerate_interpolator:先快后慢

@android:anim/anticipate_interpolator: 先后退一小步然后向前加速

@android:anim/overshoot_interpolator:快速到达终点超出一小步然后回到终点

@android:anim/anticipate_overshoot_interpolator:到达终点超出一小步然后回到终点

@android:anim/bounce_interpolator:到达终点产生弹球效果,弹几下回到终点

@android:anim/linear_interpolator:均匀速度。
ObjectAnimator使用示例:

ObjectAnimator rotationXAnimator = ObjectAnimator.ofFloat(target,
                    "rotationX",
                    0f, 360f);
            rotationXAnimator.setRepeatCount(1);
            rotationXAnimator.setDuration(3000);
            rotationXAnimator.setRepeatMode(ValueAnimator.REVERSE);
            

ObjectAnimator bgColorAnimator = ObjectAnimator.ofArgb(mPuppet,
                    "backgroundColor",
                    0xff009688, 0xff795548);
            bgColorAnimator.setRepeatCount(1);
            bgColorAnimator.setDuration(3000);
            bgColorAnimator.setRepeatMode(ValueAnimator.REVERSE);
            bgColorAnimator.setStartDelay(0);

其中属性可选,rotationX,rotationY,translationX、translationY、translationZ、scaleX、scaleY、alpha、等,规则就是,在View中查找设置属性的方法set(具体属性),将具体属性中的首字母改成小写即可,如: View.setRotationX, 在ObjectAnimator中对应的的属性名称就是rotationX。

PropertyValuesHolder示例:

也可以直接使用PropertyValuesHolder来设置动画,如下:

    PropertyValuesHolder bgColorAnimator = PropertyValuesHolder.ofObject("backgroundColor",
            new ArgbEvaluator(),
            0xff009688, 0xff795548);
    PropertyValuesHolder rotationXAnimator = PropertyValuesHolder.ofFloat("rotationX",
            0f, 360f);
    ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mPuppet, bgColorAnimator, rotationXAnimator);
    objectAnimator.setDuration(3000);
    objectAnimator.setRepeatCount(1);
    objectAnimator.setRepeatMode(ValueAnimator.REVERSE);

ObjectAnimator中的设置方法,如ofFloat最终使用的就是PropertyValuesHolder,来存储将要修改的属性内容和属性值

ValueAnimator使用示例:

ObjectAnimator继承自ValueAnimator,直接使用ValueAnimator有相比ObjectAnimator更广泛的灵活性,只是使用难度稍大,如下将修改target的宽与高做成动画效果:

    final int height = target.getLayoutParams().height;
    final int width = target.getLayoutParams().width;

    ValueAnimator sizeValueAnimator = ValueAnimator.ofFloat(1f, 3f);
    sizeValueAnimator.setDuration(3000);
    sizeValueAnimator.setRepeatCount(1);
    sizeValueAnimator.setRepeatMode(ValueAnimator.REVERSE);
    sizeValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            float animatedValue = (float) valueAnimator.getAnimatedValue();
            target.getLayoutParams().height = (int) (height * animatedValue);
            target.getLayoutParams().width = (int) (width * animatedValue);
            target.requestLayout();
        }
    });

ValueAnimator使用自定义数据计算器,可实现更加多样化的动画进度展现

    private Animator getValueAnimatorByCustom() {
        final int height = target.getLayoutParams().height;
        final int width = target.getLayoutParams().width;
        PropertyBean startPropertyBean = new PropertyBean(0xff009688, 0f, 1f);
        PropertyBean endPropertyBean = new PropertyBean(0xff795548, 360f, 3.0f);

        ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.setDuration(3000);
        valueAnimator.setInterpolator(new SpeedUpInterpolator());//custom interpolator
        valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
        valueAnimator.setRepeatCount(1);

        valueAnimator.setObjectValues(startPropertyBean, endPropertyBean);
        valueAnimator.setEvaluator(new MyTypeEvaluator());//custom evaluator

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                PropertyBean propertyBean = (PropertyBean) valueAnimator.getAnimatedValue();
                if (propertyBean.getBackgroundColor() != 0 && propertyBean.getBackgroundColor() != 1) {
                    target.setBackgroundColor(propertyBean.getBackgroundColor());
                }
                target.setRotationX(propertyBean.getRotationX());
                target.getLayoutParams().height = (int) (height * propertyBean.getSize());
                target.getLayoutParams().width = (int) (width * propertyBean.getSize());
                target.requestLayout();
            }
        });
        return valueAnimator;
    }


public class PropertyBean {
    int backgroundColor;
    float rotationX;
    float size;

    public PropertyBean(int backgroundColor, float rotationX, float size) {
        this.backgroundColor = backgroundColor;
        this.rotationX = rotationX;
        this.size = size;
    }

    public int getBackgroundColor() {
        return backgroundColor;
    }

    public void setBackgroundColor(int backgroundColor) {
        this.backgroundColor = backgroundColor;
    }

    public float getRotationX() {
        return rotationX;
    }

    public void setRotationX(float rotationX) {
        this.rotationX = rotationX;
    }

    public float getSize() {
        return size;
    }

    public void setSize(float size) {
        this.size = size;
    }
}

public class MyTypeEvaluator implements TypeEvaluator<PropertyBean> {
    ArgbEvaluator mArgbEvaluator = new ArgbEvaluator();

    @Override
    public PropertyBean evaluate(float fraction, PropertyBean startPropertyBean, PropertyBean endPropertyBean) {
        int currentColor = (int) mArgbEvaluator.evaluate(fraction, startPropertyBean.getBackgroundColor(), endPropertyBean.getBackgroundColor());
        float currentRotationX = startPropertyBean.getRotationX() + (endPropertyBean.getRotationX() - startPropertyBean.getRotationX()) * fraction;
        float currentSize = startPropertyBean.getSize() + (endPropertyBean.getSize() - startPropertyBean.getSize()) * fraction;
        return new PropertyBean((int) currentColor, currentRotationX, currentSize);
    }
}

控件状态动画使用示例:

通过animated-selector实现控件在不用状态下展示不用动画或者背景的需求,用例如下:

<!-- provide a different drawable for each state -->
<item
    android:id="@+id/pressed"
    android:drawable="@drawable/img29"
    android:state_pressed="true"/>

<item
    android:id="@id/default1"
    android:drawable="@drawable/img1"/>

<!-- specify a transition -->
<transition
    android:fromId="@+id/default1"
    android:toId="@+id/pressed">
    <animation-list>
        <item
            android:drawable="@drawable/img2"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img3"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img4"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img5"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img6"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img7"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img8"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img9"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img10"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img13"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img14"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img15"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img17"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img18"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img19"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img20"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img21"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img22"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img23"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img24"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img25"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img26"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img27"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img28"
            android:duration="100"/>
        <item
            android:drawable="@drawable/img29"
            android:duration="100"/>
    </animation-list>
</transition>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值