如何使用 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();
我试图在缩小 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();