图片的放大缩小

图片的放大缩小

点击图片,放大,再点击图片缩小。

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;

public class ZoomUtil {

private Animator mCurrentAnimator;
private int mShortAnimationDuration;
private Activity mActivity ;
 
public ZoomUtil(Activity activity){
mActivity = activity ;
mShortAnimationDuration = activity.getResources().getInteger(android.R.integer.config_shortAnimTime);
}

public void zoomImageFromThumb(final View thumbView, int imageResId) {
       // If there's an animation in progress, cancel it immediately and proceed with this one.
       if (mCurrentAnimator != null) {
           mCurrentAnimator.cancel();
       }


       // Load the high-resolution "zoomed-in" image.
       final ImageView expandedImageView = (ImageView) mActivity.findViewById(R.id.expanded_image);
       expandedImageView.setImageResource(imageResId);


       // Calculate the starting and ending bounds for the zoomed-in image. This step
       // involves lots of math. Yay, math.
       final Rect startBounds = new Rect();
       final Rect finalBounds = new Rect();
       final Point globalOffset = new Point();


       // The start bounds are the global visible rectangle of the thumbnail, and the
       // final bounds are the global visible rectangle of the container view. Also
       // set the container view's offset as the origin for the bounds, since that's
       // the origin for the positioning animation properties (X, Y).
       thumbView.getGlobalVisibleRect(startBounds);
       mActivity.findViewById(R.id.container).getGlobalVisibleRect(finalBounds, globalOffset);
       startBounds.offset(-globalOffset.x, -globalOffset.y);
       finalBounds.offset(-globalOffset.x, -globalOffset.y);
       finalBounds.top = -(globalOffset.y*3) ;


       // Adjust the start bounds to be the same aspect ratio as the final bounds using the
       // "center crop" technique. This prevents undesirable stretching during the animation.
       // Also calculate the start scaling factor (the end scaling factor is always 1.0).
       float startScale;
       if ((float) finalBounds.width() / finalBounds.height()
               > (float) startBounds.width() / startBounds.height()) {
           // Extend start bounds horizontally
           startScale = (float) startBounds.height() / finalBounds.height();
           float startWidth = startScale * finalBounds.width();
           float deltaWidth = (startWidth - startBounds.width()) / 2;
           startBounds.left -= deltaWidth;
           startBounds.right += deltaWidth;
       } else {
           // Extend start bounds vertically
           startScale = (float) startBounds.width() / finalBounds.width();
           float startHeight = startScale * finalBounds.height();
           float deltaHeight = (startHeight - startBounds.height()) / 2;
           startBounds.top -= deltaHeight;
           startBounds.bottom += deltaHeight;
       }


       // Hide the thumbnail and show the zoomed-in view. When the animation begins,
       // it will position the zoomed-in view in the place of the thumbnail.
       thumbView.setAlpha(0f);
       expandedImageView.setVisibility(View.VISIBLE);


       // Set the pivot point for SCALE_X and SCALE_Y transformations to the top-left corner of
       // the zoomed-in view (the default is the center of the view).
       expandedImageView.setPivotX(0f);
       expandedImageView.setPivotY(0f);


       // Construct and run the parallel animation of the four translation and scale properties
       // (X, Y, SCALE_X, and SCALE_Y).
       AnimatorSet set = new AnimatorSet();
       set
                .play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left,finalBounds.left))
                .with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top,finalBounds.top))
                .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X, startScale, 1f))
                .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y, startScale, 1.5f));
       set.setDuration(mShortAnimationDuration);
       set.setInterpolator(new DecelerateInterpolator());
       set.addListener(new AnimatorListenerAdapter() {
           @Override
           public void onAnimationEnd(Animator animation) {
               mCurrentAnimator = null;
           }


           @Override
           public void onAnimationCancel(Animator animation) {
               mCurrentAnimator = null;
           }
       });
       set.start();
       mCurrentAnimator = set;


       // Upon clicking the zoomed-in image, it should zoom back down to the original bounds
       // and show the thumbnail instead of the expanded image.
       final float startScaleFinal = startScale;
       expandedImageView.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View view) {
               if (mCurrentAnimator != null) {
                   mCurrentAnimator.cancel();
               }


               // Animate the four positioning/sizing properties in parallel, back to their
               // original values.
               AnimatorSet set = new AnimatorSet();
               set
                        .play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left))
                        .with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top))
                        .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X, startScaleFinal))
                        .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y, startScaleFinal));
               set.setDuration(mShortAnimationDuration);
               set.setInterpolator(new DecelerateInterpolator());
               set.addListener(new AnimatorListenerAdapter() {
                   @Override
                   public void onAnimationEnd(Animator animation) {
                       thumbView.setAlpha(1f);
                       expandedImageView.setVisibility(View.GONE);
                       mCurrentAnimator = null;
                   }


                   @Override
                   public void onAnimationCancel(Animator animation) {
                       thumbView.setAlpha(1f);
                       expandedImageView.setVisibility(View.GONE);
                       mCurrentAnimator = null;
                   }
               });
               set.start();
               mCurrentAnimator = set;
           }
       });
   }
public void zoomImageFromThumb(final View thumbView, Bitmap bitmap) {
// If there's an animation in progress, cancel it immediately and proceed with this one.
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
 
// Load the high-resolution "zoomed-in" image.
final ImageView expandedImageView = (ImageView) mActivity.findViewById(R.id.expanded_image);
expandedImageView.setImageBitmap(bitmap);
 
// Calculate the starting and ending bounds for the zoomed-in image. This step
// involves lots of math. Yay, math.
final Rect startBounds = new Rect();
final Rect finalBounds = new Rect();
final Point globalOffset = new Point();
 
// The start bounds are the global visible rectangle of the thumbnail, and the
// final bounds are the global visible rectangle of the container view. Also
// set the container view's offset as the origin for the bounds, since that's
// the origin for the positioning animation properties (X, Y).
thumbView.getGlobalVisibleRect(startBounds);
mActivity.findViewById(R.id.container).getGlobalVisibleRect(finalBounds, globalOffset);
startBounds.offset(-globalOffset.x, -globalOffset.y);
finalBounds.offset(-globalOffset.x, globalOffset.y);
finalBounds.top = -(globalOffset.y*3) ;
 
// Adjust the start bounds to be the same aspect ratio as the final bounds using the
// "center crop" technique. This prevents undesirable stretching during the animation.
// Also calculate the start scaling factor (the end scaling factor is always 1.0).
float startScale;
if ((float) finalBounds.width() / finalBounds.height()
> (float) startBounds.width() / startBounds.height()) {
// Extend start bounds horizontally
startScale = (float) startBounds.height() / finalBounds.height();
float startWidth = startScale * finalBounds.width();
float deltaWidth = (startWidth - startBounds.width()) / 2;
startBounds.left -= deltaWidth;
startBounds.right += deltaWidth;
} else {
// Extend start bounds vertically
startScale = (float) startBounds.width() / finalBounds.width();
float startHeight = startScale * finalBounds.height();
float deltaHeight = (startHeight - startBounds.height()) / 2;
startBounds.top -= deltaHeight;
startBounds.bottom += deltaHeight;
}
 
// Hide the thumbnail and show the zoomed-in view. When the animation begins,
// it will position the zoomed-in view in the place of the thumbnail.
thumbView.setAlpha(0f);
expandedImageView.setVisibility(View.VISIBLE);
 
// Set the pivot point for SCALE_X and SCALE_Y transformations to the top-left corner of
// the zoomed-in view (the default is the center of the view).
expandedImageView.setPivotX(0f);
expandedImageView.setPivotY(0f);
 
// Construct and run the parallel animation of the four translation and scale properties
// (X, Y, SCALE_X, and SCALE_Y).
AnimatorSet set = new AnimatorSet();
set
.play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left,finalBounds.left))
.with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top,finalBounds.top))
.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X, startScale, 1f))
.with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y, startScale, 1.5f));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentAnimator = null;
}
 
@Override
public void onAnimationCancel(Animator animation) {
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
 
// Upon clicking the zoomed-in image, it should zoom back down to the original bounds
// and show the thumbnail instead of the expanded image.
final float startScaleFinal = startScale;
expandedImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mCurrentAnimator != null) {
mCurrentAnimator.cancel();
}
 
// Animate the four positioning/sizing properties in parallel, back to their
// original values.
AnimatorSet set = new AnimatorSet();
set
.play(ObjectAnimator.ofFloat(expandedImageView, View.X, startBounds.left))
.with(ObjectAnimator.ofFloat(expandedImageView, View.Y, startBounds.top))
.with(ObjectAnimator
.ofFloat(expandedImageView, View.SCALE_X, startScaleFinal))
.with(ObjectAnimator
.ofFloat(expandedImageView, View.SCALE_Y, startScaleFinal));
set.setDuration(mShortAnimationDuration);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
 
@Override
public void onAnimationCancel(Animator animation) {
thumbView.setAlpha(1f);
expandedImageView.setVisibility(View.GONE);
mCurrentAnimator = null;
}
});
set.start();
mCurrentAnimator = set;
}
});
}

}


R.id.container 是最顶层的layout 容器。

<ImageView
        android:id="@+id/expanded_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"
        android:contentDescription="@string/image_contentDescription" />




原文地址:https://www.cnblogs.com/javawebsoa/p/3084652.html