public boolean getScaleFinalBounds(int position) { GridView gridView = ((MainActivity) mContext).gridView; View childView = gridView.getChildAt(position); startBounds = new Rect(); final Rect finalBounds = new Rect(); final Point globalOffset = new Point(); try { childView.getGlobalVisibleRect(startBounds); } catch (Exception e) { return false; } ((Activity) mContext) .findViewById(R.id.container) .getGlobalVisibleRect(finalBounds, globalOffset); startBounds.offset(-globalOffset.x, -globalOffset.y); finalBounds.offset(-globalOffset.x, -globalOffset.y); 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; } startScaleFinal = startScale; return true; }
private void zoomImageFromThumb(View thumbView, int position) { // If there's an animation in progress, cancel it immediately and // proceed with this one. if (mCurrentAnimator != null) { mCurrentAnimator.cancel(); } viewPager = (HackyViewPager) ((Activity) mContext).findViewById(R.id.expanded_image); viewPager.setAdapter(new SamplePagerAdapter(mThumbIds, mContext)); viewPager.setCurrentItem(position); // Calculate the starting and ending bounds for the zoomed-in image. // This step // involves lots of math. Yay, math. 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); ((Activity) mContext) .findViewById(R.id.container) .getGlobalVisibleRect(finalBounds, globalOffset); startBounds.offset(-globalOffset.x, -globalOffset.y); finalBounds.offset(-globalOffset.x, -globalOffset.y); // 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). 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; } // show the zoomed-in view. When the animation // begins, // it will position the zoomed-in view in the place of the thumbnail. viewPager.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). AnimatorSet animSet = new AnimatorSet(); animSet.setDuration(1); animSet .play(ObjectAnimator.ofFloat(viewPager, "pivotX", 0f)) .with(ObjectAnimator.ofFloat(viewPager, "pivotY", 0f)) .with(ObjectAnimator.ofFloat(viewPager, "alpha", 1.0f)); animSet.start(); // Construct and run the parallel animation of the four translation and // scale properties // (X, Y, SCALE_X, and SCALE_Y). AnimatorSet set = new AnimatorSet(); ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(((MainActivity) mContext).gridView, "alpha", 1.0f, 0.f); ObjectAnimator animatorX = ObjectAnimator.ofFloat(viewPager, "x", startBounds.left, finalBounds.left); ObjectAnimator animatorY = ObjectAnimator.ofFloat(viewPager, "y", startBounds.top, finalBounds.top); ObjectAnimator animatorScaleX = ObjectAnimator.ofFloat(viewPager, "scaleX", startScale, 1f); ObjectAnimator animatorScaleY = ObjectAnimator.ofFloat(viewPager, "scaleY", startScale, 1f); set.play(alphaAnimator) .with(animatorX) .with(animatorY) .with(animatorScaleX) .with(animatorScaleY); set.setDuration(mShortAnimationDuration); set.setInterpolator(new DecelerateInterpolator()); set.addListener( new AnimatorListenerAdapter() { public void onAnimationEnd(Animator animation) { mCurrentAnimator = null; } 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. startScaleFinal = startScale; }