ScaleAnimation开始结束位置分析[通俗易懂]

ScaleAnimation开始结束位置分析[通俗易懂]做项目的时候,需要用到动画,大小和位置都不一样。刚开始想到的是ScaleAnimation和TranslateAnimation进行组合,但实验后发现,目标位置始终不对,只用TranslateAnimation是没有问题,所以ScaleAnimation应该不只是进行了缩放经过查找资料,发现ScaleAnimation还进行起始位置的移动。ScaleAnimation分为两种情况,从本身的位置…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

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

经过查找资料,发现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下载地址

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/181773.html原文链接:https://javaforall.net

(0)
上一篇 2022年10月15日 上午11:36
下一篇 2022年10月15日 上午11:46


相关推荐

  • PostgreSQL 安装

    PostgreSQL 安装PostgreSQL 安装 1 下载 postgresql 最新版 http www postgresql org ftp source 2 解压文件 tar zxvfpostgres 14 1 tar gz3 准备工作 a 添加一个 postgreSQL 用户 注 这里名称为 postgres 因这样最易懂 补充 其他用户比如 test 要启动数据库的话 text 账号需要满足两个条件 a chown Rtestdata 即 PGDATA 以及表空间目录必须 700 b 给

    2026年3月26日
    2
  • 类 InputStreamReader[通俗易懂]

    类 InputStreamReader[通俗易懂]InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。

    2026年4月13日
    4
  • 圈真的决定你的未来?

    圈真的决定你的未来?

    2022年1月6日
    38
  • pytorch之torch.nn.Conv2d()函数详解

    pytorch之torch.nn.Conv2d()函数详解文章目录一 官方文档介绍二 torch nn Conv2d 函数详解参数详解参数 dilation 扩张卷积 也叫空洞卷积 参数 groups 分组卷积三 代码实例一 官方文档介绍官网 nn Conv2d 对由多个输入平面组成的输入信号进行二维卷积二 torch nn Conv2d 函数详解参数详解 torch nn Conv2d in channels out channels kernel size stride 1 padding 0 dilation 1 groups

    2026年3月20日
    2
  • (中英双语)从零开始构建大模型:GitHub超44K Star的大模型教程(送PDF)

    (中英双语)从零开始构建大模型:GitHub超44K Star的大模型教程(送PDF)

    2026年3月16日
    4
  • JavaScript之数组的详细介绍

    JavaScript之数组的详细介绍每一门编程语言 都有数组或类似数组的结构 同样的 JavaScript 虽然是脚本语言 也不例外 学习 JavaScript 的数组 我们从新建第一个数组开始 JavaScript 中的数组 长度是动态可变的 如果学过其他编程语言的朋友可能对这一点不是很习惯 但事实上反而使得问题变得简单了 因此不需要再定义数组的时候就指定它的大小

    2026年3月19日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号