Android 动画(Animation)中透明(alpha),平移(translate),缩放(scale),旋转(rotate),集合(set)动画等实现

一、引言

1、Android 中动画有多种, 常用的有两种, 即view动画和属性动画,这两者在视觉效果上并没太大不同, 实现方式也是大同小异, 但有一个显著区别:

        例如一个平移动画, 在视觉上都感觉控件已经离开了原来的位置, 但view动画并不改变控件对触摸和点击的响应位置, 控件的响应范围还在控件最初始的位置,点击视觉上的位置并不生效;  

        但属性动画的响应范围和位置却会随着控件动画的变化而变化。

2、另一个区别一般用不到, 也是在测试时无意发现, 对同一个控件执行不同的动画, view动画会默认清除上一个动画的效果, 但属性动画却会保留上一个动画的效果, 即属性动画连续执行多个动画而不手动清除效果, 就会变成混合动画。

3、Android 中动画设置比较简单, 但不同动画混合的效果千变万化, 项目的工具类 BasisAnimUtils 只是提供给一个参考, 具体应用时最好重新编写。

4、项目地址: https://github.com/GinGod/BasisDependency , 具体参考类:BasisAnimUtils 和 AnimationActivity

二、view动画

1、几个通用方法解释

        a. setDuration(long durationMillis)  设置单次动画播放时长, 单位是 ms(毫秒)

        b. setRepeatCount(int repeatCount)  设置动画重复次数, 常用值: Animation.INFINITE (无限次)

        c. setRepeatMode(int repeatMode)  设置重复模式,常用值: Animation.REVERSE (反转开始), Animation.RESTART(重新开始)

        d. setFillAfter(boolean fillAfter)   设置动画结束后控件停留的位置,常用值: false (默认)回到原始位置, true 停留在动画停止的最后一帧上

        e. setInterpolator(Interpolator i) (不常用)动画执行速率, 常用值:new LinearInterpolator() 匀速(在连续旋转中用到)

2、透明(alpha)动画

/**
     * 透明度渐变的动画
     */
    public static void alpha(View view) {
        AlphaAnimation aa = new AlphaAnimation(1.0f, 0.2f);
        // 动画播放的时间长度
        aa.setDuration(2000);
        // 设置重复播放的次数
        aa.setRepeatCount(Animation.INFINITE);
        // 设置重复播放的模式
        aa.setRepeatMode(Animation.REVERSE);
        //动画结束后还原到初始状态
        aa.setFillAfter(true);
        // 让iv播放aa动画
        view.startAnimation(aa);
    }

3、平移(translate)动画

        Animation.RELATIVE_TO_SELF  相对于自己

        Animation.RELATIVE_TO_PARENT  相对于父窗口

        Tip: 相对于父窗口是相对于view的直接父控件, 若控件被某一ViewGroup包裹, 测试发现动画只在父窗口范围内显示, 超出父窗口的位置不显示, 后面动画类似

/**
     * 平移动画
     */
    public static void trans(View view) {
        //相对于父窗口是相对于view的父控件, 测试发现动画只在父窗口范围内显示, 超出父窗口的位置不显示
        TranslateAnimation ta = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_PARENT, 0, Animation.RELATIVE_TO_PARENT, 0.5f);
        // 动画播放的时间长度
        ta.setDuration(2000);
        // 设置重复播放的次数
        ta.setRepeatCount(Animation.INFINITE);
        // 设置重复播放的模式
        ta.setRepeatMode(Animation.REVERSE);
        //动画结束后还原到初始状态
        ta.setFillAfter(false);
        // 让iv播放aa动画
        view.startAnimation(ta);
    }

4、缩放(scale)动画

/**
     * 缩放动画
     */
    public static void scale(View view) {
        ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        // 动画播放的时间长度
        sa.setDuration(2000);
        // 设置重复播放的次数
        sa.setRepeatCount(Animation.INFINITE);
        // 设置重复播放的模式
        sa.setRepeatMode(Animation.REVERSE);
        //动画结束后还原到初始状态
        sa.setFillAfter(false);
        // 让iv播放aa动画
        view.startAnimation(sa);
    }

5、旋转(rotate)动画

/**
     * 旋转动画
     */
    public static void rotate(View view) {
        RotateAnimation ra = new RotateAnimation(0, 360,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        // 动画播放的时间长度
        ra.setDuration(2000);
        // 设置重复播放的次数
        ra.setRepeatCount(Animation.INFINITE);
        // 设置重复播放的模式
        ra.setRepeatMode(Animation.REVERSE);
        //动画结束后还原到初始状态
        ra.setFillAfter(false);
        // 让iv播放aa动画
        view.startAnimation(ra);
    }

6、集合(set)动画

        集合动画可以将不同的动画在同一时间播放,以实现复杂的动画效果

/**
     * 动画合集 集合
     */
    public static void set(View view) {
        AnimationSet set = new AnimationSet(false);

        AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f);
        // 动画播放的时间长度
        aa.setDuration(2000);
        // 设置重复播放的次数
        aa.setRepeatCount(Animation.INFINITE);
        // 设置重复播放的模式
        aa.setRepeatMode(Animation.REVERSE);

        RotateAnimation ra = new RotateAnimation(0, 360,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        // 动画播放的时间长度
        ra.setDuration(2000);
        // 设置重复播放的次数
        ra.setRepeatCount(Animation.INFINITE);
        // 设置重复播放的模式
        ra.setRepeatMode(Animation.REVERSE);

        ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        // 动画播放的时间长度
        sa.setDuration(2000);
        // 设置重复播放的次数
        sa.setRepeatCount(Animation.INFINITE);
        // 设置重复播放的模式
        sa.setRepeatMode(Animation.REVERSE);

        TranslateAnimation ta = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0.5f);
        // 动画播放的时间长度
        ta.setDuration(2000);
        // 设置重复播放的次数
        ta.setRepeatCount(Animation.INFINITE);
        // 设置重复播放的模式
        ta.setRepeatMode(Animation.REVERSE);

        set.addAnimation(aa);
        set.addAnimation(ta);
        set.addAnimation(sa);
        set.addAnimation(ra);
        view.startAnimation(set);
    }

三、使用 .xml 资源文件实现动画

1、透明动画

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="2000"
       android:fillAfter="false"
       android:fromAlpha="0.0"
       android:interpolator="@android:anim/linear_interpolator"
       android:repeatCount="infinite"
       android:repeatMode="reverse"
       android:toAlpha="1.0">

</alpha>

2、平移动画

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
           android:duration="2000"
           android:fillAfter="false"
           android:fromXDelta="0"
           android:fromYDelta="0"
           android:repeatCount="2"
           android:repeatMode="reverse"
           android:toXDelta="25%"
           android:toYDelta="252%">

</translate>

3、缩放动画

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="2000"
       android:fillAfter="false"
       android:fromXScale="20%"
       android:fromYScale="20%"
       android:pivotX="50%"
       android:pivotY="50%"
       android:repeatCount="2"
       android:repeatMode="reverse"
       android:toXScale="200%"
       android:toYScale="200%">

</scale>

4、旋转动画

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

</rotate>

5、集合动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:fillAfter="true">

    <rotate
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="2"
        android:repeatMode="reverse"
        android:toDegrees="360">
    </rotate>

    <scale
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="2000"
        android:fromXScale="20%"
        android:fromYScale="20%"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="2"
        android:repeatMode="reverse"
        android:toXScale="200%"
        android:toYScale="200%">
    </scale>

</set>

6、代码实现

        引用资源文件实现动画就两行代码, 工具类对其进行了简单封装

/**
     * 透明度渐变的动画
     */
    public static void alpha(Context context, View view) {
        anim(context, view, R.anim.anim_view_alpha);
    }

    /**
     * 平移动画
     */
    public static void trans(Context context, View view) {
        anim(context, view, R.anim.anim_view_trans);
    }

    /**
     * 缩放动画
     */
    public static void scale(Context context, View view) {
        anim(context, view, R.anim.anim_view_scale);
    }

    /**
     * 旋转动画
     */
    public static void rotate(Context context, View view) {
        anim(context, view, R.anim.anim_view_rotate);
    }

    /**
     * 连续旋转动画
     */
    public static void rotateContinue(Context context, View view) {
        anim(context, view, R.anim.anim_view_rotate_continue);
    }

    /**
     * 动画合集 集合
     */
    public static void set(Context context, View view) {
        anim(context, view, R.anim.anim_view_set);
    }

    /**
     * 资源动画
     */
    public static void anim(Context context, View view, int animId) {
        Animation aa = AnimationUtils.loadAnimation(context, animId);
        view.startAnimation(aa);
    }

四、属性动画

        属性动画的四个基本动画都是使用的同一个类ObjectAnimator, 只是根据传入参数的不同来执行不同的动画, 参数有

                alpha  透明动画

                translationX  X方向平移动画

                translationY  Y方向平移动画

                scaleX  X方向缩放动画

                scaleY  Y方向缩放动画

                rotationX  X方向旋转动画

                rotationY  Y方向旋转动画

具体代码封装如下:

/**
     * 透明度渐变的动画
     *
     * @param view
     */
    public static void alphaOfObject(View view) {
        animOfObject(view, "alpha", new float[]{
                0.2f, 0.4f, 0.6f, 0.8f, 1.0f});
    }

    /**
     * 平移动画
     *
     * @param view
     */
    public static void transOfObject(View view) {
        animOfObject(view, "translationX",
                new float[]{10f, 20f, 30f, 40f, 60f, 80f});
    }

    /**
     * 缩放动画
     */
    public static void scaleOfObject(View view) {
        // iv.setScaleX(scaleX)
        animOfObject(view, "scaleX", new float[]{
                1f, 2f, 3f, 4f, 5f, 6f});
    }

    /**
     * 旋转动画
     */
    public static void rotateOfObject(View view) {
        animOfObject(view, "rotationY",
                new float[]{90f, 180f, 270f, 360f});
    }

    /**
     * 属性动画(执行时不会清除原有动画)
     */
    public static void animOfObject(View target, String propertyName, float... values) {
        ObjectAnimator oa = ObjectAnimator.ofFloat(target, propertyName, values);
        oa.setDuration(2000);
        oa.setRepeatCount(ObjectAnimator.INFINITE);
        oa.setRepeatMode(ObjectAnimator.REVERSE);
        oa.start();
    }

    /**
     * 属性动画合集 集合
     */
    public static void setOfObject(View view) {
        AnimatorSet set = new AnimatorSet();
        ObjectAnimator oa = ObjectAnimator.ofFloat(view, "translationX",
                new float[]{10f, 20f, 30f, 40f, 60f, 80f});
        oa.setDuration(3000);
        ObjectAnimator oa2 = ObjectAnimator.ofFloat(view, "translationY",
                new float[]{-10f, -20f, -30f, -40f, -60f, -80f});
        oa2.setDuration(3000);
        set.playTogether(oa, oa2);
        set.start();
    }

    /**
     * 清除动画
     */
    public static void clearAnimation(View... views) {
        for (int i = 0; i < views.length; i++) {
            views[0].clearAnimation();
        }
    }

五、项目地址

项目地址: https://github.com/GinGod/BasisDependency , 具体参考类:BasisAnimUtils 和 AnimationActivity

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值