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



我试图移动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();

最新更新