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下载地址

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • OpenCV学习笔记(30)KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较

    OpenCV学习笔记(30)KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较KAZE系列笔记:1. OpenCV学习笔记(27)KAZE算法原理与源码分析(一)非线性扩散滤波2. OpenCV学习笔记(28)KAZE算法原理与源码分析(二)非线性尺度空间构建3. OpenCV学习笔记(29)KAZE算法原理与源码分析(三)特征检测与描述4. OpenCV学习笔记(30)KAZE算法原理与源码分析(四)KAZE特征的性能分析与比较5. OpenCV学习笔记

  • 关于SM总线控制器驱动的安装

    关于SM总线控制器驱动的安装没有装SM总线控制器的再设备管理器看起来是这样的:虽然说,这个控制器不装对日常简单应用没有多大影响,但是为了保证计算机的性能,避免在使用过程中出现各种奇怪的问题,不装是不行的。下面开始安装,一般的驱动安装也可遵循此过程。首先解压ATISB600南桥驱动。我的版本是7.8的,解压默认再C:\ATI\********然后打开相应文件夹,如下图:红圈画的就是传说中的控制器驱动文件。…

  • Android listView中的button点击事件[通俗易懂]

    Android listView中的button点击事件[通俗易懂]Android–listView中的button控件获取item的值在listview中的listitem设置事件响应,如果listitem中有button控件,这时候listitem就不会捕获到点击事件,而默认的是listitem中的button会捕获点击事件,这方面的介绍网上很多,我想大家应该很熟悉了,之前做项目开发的时候遇到了一个问题,就是如果我点击listitem中的button怎么才能这个button是在哪一个item中呢,换句话说,就是点击listitem中的button怎么获取该list

  • 生命游戏(两),有一种东西叫CCScrollView

    生命游戏(两),有一种东西叫CCScrollView

  • stm32循迹小车详细制作过程(附加完全版代码)「建议收藏」

    stm32循迹小车详细制作过程(附加完全版代码)「建议收藏」stm32循迹小车详细制作过程一.材料准备1、主控板Stm32f103c8t6(推荐,便宜够用)2、下载器USB转TTL串口模块3、电源12v锂电池组、配套充电器(推荐下图这种,方便,好接线,12v!12v!12v!)4、电机驱动模块L298n电机驱动模块(尽量多备一两个,容易烧)5、循迹模块TCRT5000循迹模块(多买几个,四个吧)6、杜邦线公对公、母对母、公对母(都买上,不贵,消耗品)7、开关避免出现意外还是备一个吧8、小车底座有四个轮的,三个轮的(

  • python和java哪个更值得学_java和python

    python和java哪个更值得学_java和python从去年到现在IA人工智能热度一直都是上升,而且很多有经验的程序员也打出“2018年不学习Python还能学习哪种编程语言“的口号,可对于初学者来说,Python相对比较简单。Python的语法类似于伪

发表回复

您的电子邮箱地址不会被公开。

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