0
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;
}

上面两个函数用于动画缩放图像。上面代码的问题是 zoomIn 动画在开始时发生一次,但在以后没有发生。当 zoomOut 工作时。zoomIn 和 zoomOut 函数在点击图像时被调用。

行为就像单击小图像动画缩放是正确的,单击大图像动画缩小也是正确的,但是当再次单击小图像时,大图像突然出现。

我这样称呼它

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));
    }
});
4

1 回答 1

1

我认为你的实现太复杂了。尝试Transition API从 androidx (support) 包中使用,使用它的动画更容易。调用TransitionManager.beginDelayedTransition然后更改视图比例。有ChangeTransform处理比例变化的默认转换。

import androidx.transition.ChangeTransform;
import androidx.transition.Transition;
import androidx.transition.TransitionManager; 

private void onClick() {
    View imageView = findViewById(R.id.imageView);
    ViewGroup parent = findViewById(R.id.parent);

    Transition transition = new ChangeTransform();
    transition.setDuration(600);
    transition.addTarget(R.id.imageView);

    TransitionManager.beginDelayedTransition(parent, transition);
    float scale = zoom ? 1 : 0.5f;
    imageView.setScaleX(scale);
    imageView.setScaleY(scale);
}

R.id.parent是的父母ViewGroupImageView这是结果:

在此处输入图像描述

很酷的是,您可以单击上一个动画中间的图像。TransitionManager将从当前视图比例值开始新的动画。

于 2019-05-29T13:54:31.370 回答