自定义圆周运动动画理解


工作中遇到一个动画需求,于是从网上找了个例子,修改加注释理解了一下。

理解步骤如下:

1:继承Animation,复写 applyTransformation()方法

2:在applyTransformation 中实现自己的动画算法,这个方法有两个参数 p1: float 动画变化速率  p2: 动画应用       对象

3:在这个圆周运动动画中,首先确定圆周运动范围 0-360°。

4:  在动画的刷新变化中 计算x,y 的坐标,最终通过不停刷新来达到效果。

5:计算x,y时分0°,90°,180°,270°,360°。和区间 (0-90°,90-180°,180-270°,270-360°)

      然后通过三角函数计算即可。


6:动画的应用:

 

 /**
     * 播放 搜索红包动画
     */
    public void playSearchAnimation() {

        CircleAnimation animation = new CircleAnimation(50);
        animation.setDuration(1000);
        animation.setRepeatCount(1);//设置大一点儿表示无限大。
        animation.setInterpolator(new LinearInterpolator());//不停顿
//        animation.setRepeatMode(Animation.RESTART);
//        animation.setRepeatCount(Animation.INFINITE);
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                onAnmationEnd();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        loading.startAnimation(animation);
    }



7 效果:





     下面是源码:---------------------------------------------------------------------


 

package com.hanya.financing.global.utils;

import android.view.animation.Animation;
import android.view.animation.Transformation;


/**
 * 圆周运动动画效果
 */
public class CircleAnimation extends Animation {

    private int radii;

    public CircleAnimation(int radii) {
        this.radii = radii;
    }

    /**
     * @param interpolatedTime 取值范围 0-1
     * @param t
     */
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        //根据取值范围 确定圆周运动的角度范围。0-360
//        float d = 360 * interpolatedTime ;//+ 180;  //算法一
        float d = 360 * interpolatedTime + 180;       //算法二
        DebugUtil.e("--->" + d);
        if (d > 360) { //算法二
            d = d - 360;
        }
        //根据取值范围 确定圆周运动的角度范围。0-360
        int[] ps = getNewLocation((int) d, radii, 0, 0);//
        t.getMatrix().setTranslate(ps[0], ps[1] - radii);
    }

    /**
     * @param newAngle 当前临时角度
     * @param r        半径
     * @param width    控件的宽
     * @param height   控件的高
     * @return
     */
    public int[] getNewLocation(int newAngle, int r, int width, int height) {
        int newAngle1;
        int newX = 0, newY = 0;
        /**
         * 0-90
         */
        if (newAngle == 0) {
            newX = width;
            newY = height - r;
        } else if (newAngle == 90) {
            newX = width + r;
            newY = height;
        } else if (newAngle == 180) {
            newX = width;
            newY = height + r;
        } else if (newAngle == 270) {
            newX = width - r;
            newY = height;
        } else if (newAngle == 360) {
            newX = width;
            newY = height - r;
        } else if (newAngle > 360) {
            newX = width;
            newY = height - r;
        } else if (newAngle > 0 && newAngle < 90) {
            // 0-90  baidu:就拿sin30°为列:Math.sin(30*Math.PI/180)
            // 思路为PI相当于π,而此时的PI在角度值里相当于180°,
            // 所以Math.PI/180得到的结果就是1°,然后再乘以30就得到相应的30°
            newX = (int) (width + (r * Math.sin(newAngle * Math.PI / 180)));
            newY = (int) (height - (r * Math.cos(newAngle * Math.PI / 180)));
        } else if (newAngle > 90 && newAngle < 180) {// 90-180
            newAngle1 = 180 - newAngle;
            newX = (int) (width + (r * Math.sin(newAngle1 * Math.PI / 180)));
            newY = (int) (height + (r * Math.cos(newAngle1 * Math.PI / 180)));
        } else if (newAngle > 180 && newAngle < 270) {//180-270
            newAngle1 = 270 - newAngle;
            newX = (int) (width - (r * Math.cos(newAngle1 * Math.PI / 180)));
            newY = (int) (height + (r * Math.sin(newAngle1 * Math.PI / 180)));
        } else if (newAngle > 270 && newAngle < 360) {//270-360
            newAngle1 = 360 - newAngle;
            newX = (int) (width - (r * Math.sin(newAngle1 * Math.PI / 180)));
            newY = (int) (height - (r * Math.cos(newAngle1 * Math.PI / 180)));
        }

        return new int[]{newX, newY};
    }

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值