ScaleAnimation开始结束位置分析

做项目的时候,需要用到动画,大小和位置都不一样。刚开始想到的是ScaleAnimation和TranslateAnimation进行组合,但实验后发现,目标位置始终不对,只用TranslateAnimation是没有问题,所以ScaleAnimation应该不只是进行了缩放

经过查找资料,发现ScaleAnimation还进行起始位置的移动。ScaleAnimation分为两种情况,从本身的位置缩放到另一个位置和从另一个位置缩放到本身的位置

先看一下处理后的效果

看一下ScaleAnimation的构造函数

    /**
     * fromX 在x轴方向,起始缩放比例
     * toX 在x轴上,目标缩放比例
     * fromY 在y轴方向,起始缩放比例
     * toY 在y轴上,目标缩放比例
     * pivotX 缩放的中心轴位置,这个跟我们自己的理解不一样,要通过算法算出来,这两种情况的算法还不一样
     * pivotY
     */
    public ScaleAnimation(float fromX, float toX, float fromY, float toY,
            float pivotX, float pivotY) {
        mResources = null;
        mFromX = fromX;
        mToX = toX;
        mFromY = fromY;
        mToY = toY;

        mPivotXType = ABSOLUTE;
        mPivotYType = ABSOLUTE;
        mPivotXValue = pivotX;
        mPivotYValue = pivotY;
        initializePivotPoint();
    }


fromX, toX, fromY, toY这4个参数很好理解,我们重点看一下pivotX,pivotY是怎么计算的


- 从本身的位置缩放到另一个位置
这种情况下,我们关心的是缩放后的目标位置,这里有几个值需要先了解一些,目标view的右边(targetRight),初始view左边的距离(sourceLeft),pivotX,初始view的宽(sourceWidth),放大的值(toX),他们的关系如下
targetRight - sourceLeft = pivotX - (pivotX - sourceWidth) * toX,那么pivotX的值是pivotX = (targetRight - sourceLeft - sourceWidth * toX) / (1 - toX)

pivotY的值类似,就不在描述了。

- 从另一个位置缩放到本身的位置
这种情况我们关心的是开始的位置,它们的关系是sourceLeft - targetLeft = pivotX * (1 - scaleX),那么pivotX = (sourceLeft - targetLeft) / (1 - fromX)理清楚这个后,动画效果有缩放和移动的,只需要一个ScaleAnimation就能完成。

 

为了方便后期使用写了一个帮助类

public class TranslateAnimHelper {
    public static Animation tanslateScaleAnim(boolean fromOrigin, Rect sourceRect, Rect targetRect){
        Animation anim = null;

        float sx = targetRect.width() * 1.0f / sourceRect.width();
        float sy = targetRect.height() * 1.0f / sourceRect.height();

        boolean isScale = sx != 1 || sy != 1;

        if(isScale){
            anim = scaleAnim(fromOrigin, sourceRect, targetRect);
        }else{
            if(fromOrigin){
                int fromDeltaX = 0;
                int toDeltaX = targetRect.left - sourceRect.left;
                int fromDeltaY = 0;
                int toDeltaY = targetRect.top - sourceRect.top;

                anim = new TranslateAnimation(fromDeltaX, toDeltaX, fromDeltaY, toDeltaY);
            }else {
                int fromDeltaX = -(targetRect.left - sourceRect.left);
                int toDeltaX = 0;
                int fromDeltaY = -(targetRect.top - sourceRect.top);
                int toDeltaY = 0;
                anim = new TranslateAnimation(fromDeltaX, toDeltaX, fromDeltaY, toDeltaY);
            }
        }

        return anim;
    }


    public static Animation scaleAnim(boolean fromOrigin, Rect sourceRect, Rect targetRect){
        float sx = targetRect.width() * 1.0f / sourceRect.width();
        float sy = targetRect.height() * 1.0f / sourceRect.height();

        Animation animation = null;
        if(fromOrigin){
            float fromX = 1;
            float toX = sx;
            float fromY = 1;
            float toY = sy;

            float px = (targetRect.right - sourceRect.left - sourceRect.width() * sx) / (1 - toX);
            float py = (targetRect.bottom - sourceRect.top - sourceRect.height() * sy) / (1 - toY);

            animation = new ScaleAnimation(fromX, toX, fromY, toY, px, py);
        }else{

            float fromX =  1 / sx;
            float toX = 1;
            float fromY = 1 / sy;
            float toY = 1;

            float px = (sourceRect.left - targetRect.left) / (1 - fromX);
            float py = (sourceRect.top - targetRect.top) / (1 - fromY);

            animation = new ScaleAnimation(fromX, toX, fromY, toY, px, py);
        }

        return animation;
    }
}

github下载地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值