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工作时。在点击图片时调用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));
}
});
答案 0 :(得分:0)
我认为您的实现过于复杂。尝试使用androidx(支持)程序包中的Transition API
,用它制作动画要容易得多。调用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
是ViewGroup
的父ImageView
。结果如下:
很酷的事情是,您可以单击上一个动画中间的图像。 TransitionManager
将根据当前的视图比例值开始新的动画。