简体   繁体   English

动画只发生一次

[英]Animation only happens one time

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. 以上两个功能用于动画缩放图像的zoomIn和zoomOut。 The problem with above code is the zoomIn animation is happening one once that is at the beginning but not on later time. 上面代码的问题是zoomIn动画一次发生在开始但不是在以后的时间。 While zoomOut is working. 而zoomOut正在工作。 The zoomIn and zoomOut function is being called on click action on image. 正在对图像上的单击操作调用zoomIn和zoomOut函数。

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 API from androidx (support) package, animations with it are much easier. 尝试使用来自androidx(支持)包的Transition API ,使用它的动画更加容易。 Call TransitionManager.beginDelayedTransition then change view scale. 调用TransitionManager.beginDelayedTransition然后更改视图比例。 There is default ChangeTransform transition which handle scale changes. 存在默认的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 is parent ViewGroup of ImageView . R.id.parentImageViewViewGroup Here is result: 结果如下:

在此输入图像描述

Cool thing is that you can click on image in the middle of previous animation. 很酷的是你可以点击上一个动画中间的图像。 TransitionManager will start new animation from current view scale values. TransitionManager将从当前视图比例值开始新动画。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM