如何使用 ObjectAnimator 正确缩放 ImageView 并将其移动到绝对位置

How to correctly scale and move an ImageView to an absolute position using ObjectAnimator

我试图在缩小 ImageView 后移动它,但由于某种原因,该位置与目标位置不匹配。首先,我计算比例因子和新旧位置之间的差异。然后我开始动画,但是 ImageView 移动到左边和底部很远,我不知道为什么。

float scaleX = (destWidth * 1.0f) / imageView.getMeasuredWidth();
float scaleY = (destHeight * 1.0f) / imageView.getMeasuredHeight();
float moveX = -1 * (imageView.getLeft() - destX);   // move image to the left
float moveY = destY - imageView.getTop();           // move image to the bottom

oa = ObjectAnimator.ofPropertyValuesHolder(imageView
        , PropertyValuesHolder.ofFloat("scaleX", scaleX)
        , PropertyValuesHolder.ofFloat("scaleY", scaleY)
        , PropertyValuesHolder.ofFloat("translationX", moveX)
        , PropertyValuesHolder.ofFloat("translationY", moveY));

oa.setDuration(3000);
oa.setRepeatMode(ValueAnimator.REVERSE);
oa.setRepeatCount(ValueAnimator.INFINITE);
oa.start();

我自己弄明白了,但我会在下面留下更正后的代码,供有类似问题的其他人使用。

基本上,ImageView是先根据平移移动,再按比例缩小。缩放将顶部、底部、左侧和右侧移动到中心,因此 ImageView 发生偏移。

要修复旧 ImageView 大小和新 ImageView 大小之间的一半差异,需要从之前的 moveX/moveY 中减去。

float moveX = -1 * (imageView.getLeft() - destX) 
          - ((imageView.getMeasuredWidth() - (imageView.getMeasuredWidth() * scaleX)) / 2);
// move image to the bottom   
float moveY = destY - imageView.getTop() 
          - ((imageView.getMeasuredHeight() - (imageView.getMeasuredHeight() * scaleY)) / 2);           

最后,完成的代码应该是这样的。

float scaleX = (destWidth * 1.0f) / imageView.getMeasuredWidth();
float scaleY = (destHeight * 1.0f) / imageView.getMeasuredHeight();
// move image to the left
float moveX = -1 * (imageView.getLeft() - destX) 
          - ((imageView.getMeasuredWidth() - (imageView.getMeasuredWidth() * scaleX)) / 2);
// move image to the bottom   
float moveY = destY - imageView.getTop() 
          - ((imageView.getMeasuredHeight() - (imageView.getMeasuredHeight() * scaleY)) / 2);           

oa = ObjectAnimator.ofPropertyValuesHolder(imageView
        , PropertyValuesHolder.ofFloat("scaleX", scaleX)
        , PropertyValuesHolder.ofFloat("scaleY", scaleY)
        , PropertyValuesHolder.ofFloat("translationX", moveX)
        , PropertyValuesHolder.ofFloat("translationY", moveY));

oa.setDuration(3000);
oa.setRepeatMode(ValueAnimator.REVERSE);
oa.setRepeatCount(ValueAnimator.INFINITE);
oa.start();