public static Animator zoomInImage(ImageView smallImage, ImageView largeImage, long duration) {
Rect startBounds = new Rect();
Rect endBounds = new Rect();
Point globalOffset = new Point();
smallImage.getGlobalVisibleRect(startBounds);
largeImage.getGlobalVisibleRect(endBounds, globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
endBounds.offset(-globalOffset.x, -globalOffset.y);
float startScale;
if ((float) endBounds.width() / endBounds.height()
> (float) startBounds.width() / startBounds.height()) {
// Extend start bounds horizontally
startScale = (float) startBounds.height() / endBounds.height();
float startWidth = startScale * endBounds.width();
float deltaWidth = (startWidth - startBounds.width()) / 2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
} else {
// Extend start bounds vertically
startScale = (float) startBounds.width() / endBounds.width();
float startHeight = startScale * endBounds.height();
float deltaHeight = (startHeight - startBounds.height()) / 2;
startBounds.top -= deltaHeight;
startBounds.bottom += deltaHeight;
}
smallImage.setAlpha(0f);
largeImage.setPivotX(0f);
largeImage.setPivotY(0f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet
.play(ObjectAnimator.ofFloat(largeImage, View.X, startBounds.left, endBounds.left))
.with(ObjectAnimator.ofFloat(largeImage, View.Y, startBounds.top, endBounds.top))
.with(ObjectAnimator.ofFloat(largeImage, View.SCALE_X, startScale, 1f))
.with(ObjectAnimator.ofFloat(largeImage, View.SCALE_Y, startScale, 1f));
animatorSet.setDuration(duration);
animatorSet.setInterpolator(new DecelerateInterpolator());
animatorSet.start();
largeImage.setVisibility(View.VISIBLE);
return animatorSet;
}
public static Animator zoomOutImage(final ImageView smallImage, final ImageView largeImage, long duration) {
Rect startBounds = new Rect();
Rect endBounds = new Rect();
Point globalOffset = new Point();
smallImage.getGlobalVisibleRect(startBounds);
largeImage.getGlobalVisibleRect(endBounds, globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
endBounds.offset(-globalOffset.x, -globalOffset.y);
float startScale;
if ((float) endBounds.width() / endBounds.height()
> (float) startBounds.width() / startBounds.height()) {
// Extend start bounds horizontally
startScale = (float) startBounds.height() / endBounds.height();
float startWidth = startScale * endBounds.width();
float deltaWidth = (startWidth - startBounds.width()) / 2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
} else {
// Extend start bounds vertically
startScale = (float) startBounds.width() / endBounds.width();
float startHeight = startScale * endBounds.height();
float deltaHeight = (startHeight - startBounds.height()) / 2;
startBounds.top -= deltaHeight;
startBounds.bottom += deltaHeight;
}
largeImage.setPivotX(0f);
largeImage.setPivotY(0f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet
.play(ObjectAnimator.ofFloat(largeImage, View.X, startBounds.left))
.with(ObjectAnimator.ofFloat(largeImage, View.Y, startBounds.top))
.with(ObjectAnimator.ofFloat(largeImage, View.SCALE_X, startScale))
.with(ObjectAnimator.ofFloat(largeImage, View.SCALE_Y, startScale));
animatorSet.setDuration(duration);
animatorSet.setInterpolator(new DecelerateInterpolator());
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
smallImage.setAlpha(1f);
largeImage.setVisibility(View.INVISIBLE);
}
@Override
public void onAnimationCancel(Animator animation) {
smallImage.setAlpha(1f);
largeImage.setVisibility(View.INVISIBLE);
}
});
animatorSet.start();
return animatorSet;
}
The above two function is for animating zoomIn and zoomOut of image. The problem with above code is the zoomIn animation is happening one once that is at the beginning but not on later time. While zoomOut is working. The zoomIn and zoomOut function is being called on click action on image.
The behaviour is like on click of small image animation to zoom is correct and on click of large image animation to zoom out is also correct but when small image is clicked again the large image appears suddenly.
I am calling it like this
lImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (currentAnim != null) currentAnim.cancel();
currentAnim = ZoomAnimator.zoomOutImage(sImageView, lImageView, getResources().getInteger(
android.R.integer.config_shortAnimTime));
}
});
sImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (currentAnim != null) currentAnim.cancel();
currentAnim = ZoomAnimator.zoomInImage(sImageView, lImageView, getResources().getInteger(
android.R.integer.config_shortAnimTime));
}
});
I think your implementation is too complicated. Try to use
Transition APIfrom androidx (support) package, animations with it are much easier. CallTransitionManager.beginDelayedTransitionthen change view scale. There is defaultChangeTransformtransition which handle scale changes.R.id.parentis parentViewGroupofImageView. Here is result:Cool thing is that you can click on image in the middle of previous animation.
TransitionManagerwill start new animation from current view scale values.