I am trying to move an ImageView after scaling it down, but for some reason, the position does not match the destinated position. First I calculate the scaling factors and the difference between the new and old positions. Then I started the animation, but the ImageView moves to far to the left and to the bottom and I have no clue why.
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();
CodePudding user response:
I figured it out myself, but I will leave the corrected code below for others with similar problems.
Basically, the ImageView is first moved according to the translation and then scaled down. The scaling moves the top, bottom, left and right to the center and therefore the ImageView is offset.
To fix this half of the difference between the old ImageView size and the new ImageView size needs to be subtracted from the previous 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);
Finally, the finished code should look like this.
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();