Loading packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +17 −23 Original line number Diff line number Diff line Loading @@ -32,8 +32,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; import android.text.TextUtils; import android.transition.Transition; import android.transition.TransitionListenerAdapter; import android.util.Log; import android.view.ScrollCaptureResponse; import android.view.View; Loading Loading @@ -74,7 +72,7 @@ public class LongScreenshotActivity extends Activity { private final Executor mUiExecutor; private final Executor mBackgroundExecutor; private final ImageExporter mImageExporter; private final LongScreenshotHolder mLongScreenshotHolder; private final LongScreenshotData mLongScreenshotHolder; private ImageView mPreview; private ImageView mTransitionView; Loading Loading @@ -103,7 +101,7 @@ public class LongScreenshotActivity extends Activity { @Inject public LongScreenshotActivity(UiEventLogger uiEventLogger, ImageExporter imageExporter, @Main Executor mainExecutor, @Background Executor bgExecutor, LongScreenshotHolder longScreenshotHolder) { LongScreenshotData longScreenshotHolder) { mUiEventLogger = uiEventLogger; mUiExecutor = mainExecutor; mBackgroundExecutor = bgExecutor; Loading @@ -116,7 +114,6 @@ public class LongScreenshotActivity extends Activity { public void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate(savedInstanceState = " + savedInstanceState + ")"); super.onCreate(savedInstanceState); postponeEnterTransition(); setContentView(R.layout.long_screenshot); mPreview = requireViewById(R.id.preview); Loading Loading @@ -210,13 +207,11 @@ public class LongScreenshotActivity extends Activity { public boolean onPreDraw() { mEnterTransitionView.getViewTreeObserver().removeOnPreDrawListener(this); updateImageDimensions(); startPostponedEnterTransition(); if (isActivityTransitionRunning()) { getWindow().getSharedElementEnterTransition().addListener( new TransitionListenerAdapter() { @Override public void onTransitionEnd(Transition transition) { super.onTransitionEnd(transition); mEnterTransitionView.post(() -> { Rect dest = new Rect(); mEnterTransitionView.getBoundsOnScreen(dest); mLongScreenshotHolder.takeTransitionDestinationCallback() .setTransitionDestination(dest, () -> { mPreview.animate().alpha(1f); mCropView.setBoundaryPosition( CropView.CropBoundary.TOP, topFraction); Loading @@ -226,9 +221,8 @@ public class LongScreenshotActivity extends Activity { mCropView.setVisibility(View.VISIBLE); setButtonsEnabled(true); mEnterTransitionView.setVisibility(View.GONE); } }); } }); return true; } }); Loading packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotHolder.java→packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotData.java +21 −4 Original line number Diff line number Diff line Loading @@ -23,16 +23,19 @@ import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; /** * LongScreenshotHolder holds on to 1 LongScreenshot reference to facilitate indirect in-process * passing. * LongScreenshotData holds on to 1 LongScreenshot reference and 1 TransitionDestination * reference, to facilitate indirect in-process passing. */ @SysUISingleton public class LongScreenshotHolder { public class LongScreenshotData { private final AtomicReference<ScrollCaptureController.LongScreenshot> mLongScreenshot; private final AtomicReference<ScreenshotController.TransitionDestination> mTransitionDestinationCallback; @Inject public LongScreenshotHolder() { public LongScreenshotData() { mLongScreenshot = new AtomicReference<>(); mTransitionDestinationCallback = new AtomicReference<>(); } /** Loading @@ -56,4 +59,18 @@ public class LongScreenshotHolder { return mLongScreenshot.getAndSet(null); } /** * Set the holder's TransitionDestination callback. */ public void setTransitionDestinationCallback( ScreenshotController.TransitionDestination destination) { mTransitionDestinationCallback.set(destination); } /** * Return the current TransitionDestination callback and clear. */ public ScreenshotController.TransitionDestination takeTransitionDestinationCallback() { return mTransitionDestinationCallback.getAndSet(null); } } packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +54 −17 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationRunner; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; import android.view.ScrollCaptureResponse; import android.view.SurfaceControl; Loading @@ -72,6 +73,7 @@ import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.widget.Toast; Loading Loading @@ -203,6 +205,15 @@ public class ScreenshotController { void onActionsReady(ScreenshotController.QuickShareData quickShareData); } interface TransitionDestination { /** * Allows the long screenshot activity to call back with a destination location (the bounds * on screen of the destination for the transitioning view) and a Runnable to be run once * the transition animation is complete. */ void setTransitionDestination(Rect transitionDestination, Runnable onTransitionEnd); } // These strings are used for communicating the action invoked to // ScreenshotNotificationSmartActionsProvider. static final String EXTRA_ACTION_TYPE = "android:screenshot_action_type"; Loading Loading @@ -241,7 +252,7 @@ public class ScreenshotController { private final PhoneWindow mWindow; private final DisplayManager mDisplayManager; private final ScrollCaptureController mScrollCaptureController; private final LongScreenshotHolder mLongScreenshotHolder; private final LongScreenshotData mLongScreenshotHolder; private ScreenshotView mScreenshotView; private Bitmap mScreenBitmap; Loading Loading @@ -286,7 +297,7 @@ public class ScreenshotController { ImageExporter imageExporter, @Main Executor mainExecutor, ScrollCaptureController scrollCaptureController, LongScreenshotHolder longScreenshotHolder) { LongScreenshotData longScreenshotHolder) { mScreenshotSmartActions = screenshotSmartActions; mNotificationsController = screenshotNotificationsController; mScrollCaptureClient = scrollCaptureClient; Loading Loading @@ -648,17 +659,29 @@ public class ScreenshotController { } mLongScreenshotHolder.setLongScreenshot(longScreenshot); mLongScreenshotHolder.setTransitionDestinationCallback( (transitionDestination, onTransitionEnd) -> mScreenshotView.startLongScreenshotTransition( transitionDestination, onTransitionEnd, longScreenshot)); final Intent intent = new Intent(mContext, LongScreenshotActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); Pair<ActivityOptions, ExitTransitionCoordinator> transition = ActivityOptions.startSharedElementAnimation( mWindow, new ScreenshotExitTransitionCallbacks(), null, Pair.create(mScreenshotView.getScrollablePreview(), ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME)); ActivityOptions.startSharedElementAnimation(mWindow, new ScreenshotExitTransitionCallbacksSupplier(false).get(), null); transition.second.startExit(); mContext.startActivity(intent, transition.first.toBundle()); RemoteAnimationAdapter runner = new RemoteAnimationAdapter( SCREENSHOT_REMOTE_RUNNER, 0, 0); try { WindowManagerGlobal.getWindowManagerService() .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY); } catch (Exception e) { Log.e(TAG, "Error overriding screenshot app transition", e); } }, mMainExecutor); }); } catch (CancellationException e) { Loading Loading @@ -883,8 +906,8 @@ public class ScreenshotController { return () -> { Pair<ActivityOptions, ExitTransitionCoordinator> transition = ActivityOptions.startSharedElementAnimation( mWindow, new ScreenshotExitTransitionCallbacks(), null, Pair.create(mScreenshotView.getScreenshotPreview(), mWindow, new ScreenshotExitTransitionCallbacksSupplier(true).get(), null, Pair.create(mScreenshotView.getScreenshotPreview(), ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME)); transition.second.startExit(); Loading Loading @@ -970,7 +993,17 @@ public class ScreenshotController { return matchWithinTolerance; } private class ScreenshotExitTransitionCallbacks implements ExitTransitionCallbacks { private class ScreenshotExitTransitionCallbacksSupplier implements Supplier<ExitTransitionCallbacks> { final boolean mDismissOnHideSharedElements; ScreenshotExitTransitionCallbacksSupplier(boolean dismissOnHideSharedElements) { mDismissOnHideSharedElements = dismissOnHideSharedElements; } @Override public ExitTransitionCallbacks get() { return new ExitTransitionCallbacks() { @Override public boolean isReturnTransitionAllowed() { return false; Loading @@ -978,11 +1011,15 @@ public class ScreenshotController { @Override public void hideSharedElements() { if (mDismissOnHideSharedElements) { finishDismiss(); } } @Override public void onFinish() { } }; } } } packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +47 −3 Original line number Diff line number Diff line Loading @@ -764,7 +764,53 @@ public class ScreenshotView extends FrameLayout implements return r; } void startLongScreenshotTransition(Rect destination, Runnable onTransitionEnd, ScrollCaptureController.LongScreenshot longScreenshot) { mScrollablePreview.setImageBitmap(longScreenshot.toBitmap()); ValueAnimator anim = ValueAnimator.ofFloat(0, 1); float startX = mScrollablePreview.getX(); float startY = mScrollablePreview.getY(); int[] locInScreen = mScrollablePreview.getLocationOnScreen(); destination.offset((int) startX - locInScreen[0], (int) startY - locInScreen[1]); mScrollablePreview.setPivotX(0); mScrollablePreview.setPivotY(0); mScrollablePreview.setAlpha(1f); float currentScale = mScrollablePreview.getWidth() / (float) longScreenshot.getWidth(); Matrix matrix = new Matrix(); matrix.setScale(currentScale, currentScale); matrix.postTranslate( longScreenshot.getLeft() * currentScale, longScreenshot.getTop() * currentScale); mScrollablePreview.setImageMatrix(matrix); float destinationScale = destination.width() / (float) mScrollablePreview.getWidth(); anim.addUpdateListener(animation -> { float t = animation.getAnimatedFraction(); mScrollingScrim.setAlpha(1 - t); float currScale = MathUtils.lerp(1, destinationScale, t); mScrollablePreview.setScaleX(currScale); mScrollablePreview.setScaleY(currScale); mScrollablePreview.setX(MathUtils.lerp(startX, destination.left, t)); mScrollablePreview.setY(MathUtils.lerp(startY, destination.top, t)); }); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); onTransitionEnd.run(); mScrollablePreview.animate().alpha(0).setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mCallbacks.onDismiss(); } }); } }); anim.start(); } void prepareScrollingTransition(ScrollCaptureResponse response, Bitmap screenBitmap) { mScrollingScrim.setImageBitmap(screenBitmap); mScrollingScrim.setVisibility(View.VISIBLE); Rect scrollableArea = scrollableAreaOnScreen(response); float scale = mCornerSizeX / (mOrientationPortrait ? screenBitmap.getWidth() : screenBitmap.getHeight()); Loading @@ -775,14 +821,12 @@ public class ScreenshotView extends FrameLayout implements params.height = (int) (scale * scrollableArea.height()); Matrix matrix = new Matrix(); matrix.setScale(scale, scale); matrix.postTranslate(0, -scrollableArea.top * scale); matrix.postTranslate(-scrollableArea.left * scale, -scrollableArea.top * scale); mScrollablePreview.setTranslationX(scale * scrollableArea.left); mScrollablePreview.setTranslationY(scale * scrollableArea.top); mScrollablePreview.setImageMatrix(matrix); mScrollingScrim.setImageBitmap(screenBitmap); mScrollingScrim.setVisibility(View.VISIBLE); mScrollablePreview.setImageBitmap(screenBitmap); mScrollablePreview.setVisibility(View.VISIBLE); createScreenshotFadeDismissAnimation(true).start(); Loading Loading
packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java +17 −23 Original line number Diff line number Diff line Loading @@ -32,8 +32,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; import android.text.TextUtils; import android.transition.Transition; import android.transition.TransitionListenerAdapter; import android.util.Log; import android.view.ScrollCaptureResponse; import android.view.View; Loading Loading @@ -74,7 +72,7 @@ public class LongScreenshotActivity extends Activity { private final Executor mUiExecutor; private final Executor mBackgroundExecutor; private final ImageExporter mImageExporter; private final LongScreenshotHolder mLongScreenshotHolder; private final LongScreenshotData mLongScreenshotHolder; private ImageView mPreview; private ImageView mTransitionView; Loading Loading @@ -103,7 +101,7 @@ public class LongScreenshotActivity extends Activity { @Inject public LongScreenshotActivity(UiEventLogger uiEventLogger, ImageExporter imageExporter, @Main Executor mainExecutor, @Background Executor bgExecutor, LongScreenshotHolder longScreenshotHolder) { LongScreenshotData longScreenshotHolder) { mUiEventLogger = uiEventLogger; mUiExecutor = mainExecutor; mBackgroundExecutor = bgExecutor; Loading @@ -116,7 +114,6 @@ public class LongScreenshotActivity extends Activity { public void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate(savedInstanceState = " + savedInstanceState + ")"); super.onCreate(savedInstanceState); postponeEnterTransition(); setContentView(R.layout.long_screenshot); mPreview = requireViewById(R.id.preview); Loading Loading @@ -210,13 +207,11 @@ public class LongScreenshotActivity extends Activity { public boolean onPreDraw() { mEnterTransitionView.getViewTreeObserver().removeOnPreDrawListener(this); updateImageDimensions(); startPostponedEnterTransition(); if (isActivityTransitionRunning()) { getWindow().getSharedElementEnterTransition().addListener( new TransitionListenerAdapter() { @Override public void onTransitionEnd(Transition transition) { super.onTransitionEnd(transition); mEnterTransitionView.post(() -> { Rect dest = new Rect(); mEnterTransitionView.getBoundsOnScreen(dest); mLongScreenshotHolder.takeTransitionDestinationCallback() .setTransitionDestination(dest, () -> { mPreview.animate().alpha(1f); mCropView.setBoundaryPosition( CropView.CropBoundary.TOP, topFraction); Loading @@ -226,9 +221,8 @@ public class LongScreenshotActivity extends Activity { mCropView.setVisibility(View.VISIBLE); setButtonsEnabled(true); mEnterTransitionView.setVisibility(View.GONE); } }); } }); return true; } }); Loading
packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotHolder.java→packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotData.java +21 −4 Original line number Diff line number Diff line Loading @@ -23,16 +23,19 @@ import java.util.concurrent.atomic.AtomicReference; import javax.inject.Inject; /** * LongScreenshotHolder holds on to 1 LongScreenshot reference to facilitate indirect in-process * passing. * LongScreenshotData holds on to 1 LongScreenshot reference and 1 TransitionDestination * reference, to facilitate indirect in-process passing. */ @SysUISingleton public class LongScreenshotHolder { public class LongScreenshotData { private final AtomicReference<ScrollCaptureController.LongScreenshot> mLongScreenshot; private final AtomicReference<ScreenshotController.TransitionDestination> mTransitionDestinationCallback; @Inject public LongScreenshotHolder() { public LongScreenshotData() { mLongScreenshot = new AtomicReference<>(); mTransitionDestinationCallback = new AtomicReference<>(); } /** Loading @@ -56,4 +59,18 @@ public class LongScreenshotHolder { return mLongScreenshot.getAndSet(null); } /** * Set the holder's TransitionDestination callback. */ public void setTransitionDestinationCallback( ScreenshotController.TransitionDestination destination) { mTransitionDestinationCallback.set(destination); } /** * Return the current TransitionDestination callback and clear. */ public ScreenshotController.TransitionDestination takeTransitionDestinationCallback() { return mTransitionDestinationCallback.getAndSet(null); } }
packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +54 −17 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ import android.view.IRemoteAnimationFinishedCallback; import android.view.IRemoteAnimationRunner; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; import android.view.ScrollCaptureResponse; import android.view.SurfaceControl; Loading @@ -72,6 +73,7 @@ import android.view.ViewTreeObserver; import android.view.Window; import android.view.WindowInsets; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.widget.Toast; Loading Loading @@ -203,6 +205,15 @@ public class ScreenshotController { void onActionsReady(ScreenshotController.QuickShareData quickShareData); } interface TransitionDestination { /** * Allows the long screenshot activity to call back with a destination location (the bounds * on screen of the destination for the transitioning view) and a Runnable to be run once * the transition animation is complete. */ void setTransitionDestination(Rect transitionDestination, Runnable onTransitionEnd); } // These strings are used for communicating the action invoked to // ScreenshotNotificationSmartActionsProvider. static final String EXTRA_ACTION_TYPE = "android:screenshot_action_type"; Loading Loading @@ -241,7 +252,7 @@ public class ScreenshotController { private final PhoneWindow mWindow; private final DisplayManager mDisplayManager; private final ScrollCaptureController mScrollCaptureController; private final LongScreenshotHolder mLongScreenshotHolder; private final LongScreenshotData mLongScreenshotHolder; private ScreenshotView mScreenshotView; private Bitmap mScreenBitmap; Loading Loading @@ -286,7 +297,7 @@ public class ScreenshotController { ImageExporter imageExporter, @Main Executor mainExecutor, ScrollCaptureController scrollCaptureController, LongScreenshotHolder longScreenshotHolder) { LongScreenshotData longScreenshotHolder) { mScreenshotSmartActions = screenshotSmartActions; mNotificationsController = screenshotNotificationsController; mScrollCaptureClient = scrollCaptureClient; Loading Loading @@ -648,17 +659,29 @@ public class ScreenshotController { } mLongScreenshotHolder.setLongScreenshot(longScreenshot); mLongScreenshotHolder.setTransitionDestinationCallback( (transitionDestination, onTransitionEnd) -> mScreenshotView.startLongScreenshotTransition( transitionDestination, onTransitionEnd, longScreenshot)); final Intent intent = new Intent(mContext, LongScreenshotActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); Pair<ActivityOptions, ExitTransitionCoordinator> transition = ActivityOptions.startSharedElementAnimation( mWindow, new ScreenshotExitTransitionCallbacks(), null, Pair.create(mScreenshotView.getScrollablePreview(), ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME)); ActivityOptions.startSharedElementAnimation(mWindow, new ScreenshotExitTransitionCallbacksSupplier(false).get(), null); transition.second.startExit(); mContext.startActivity(intent, transition.first.toBundle()); RemoteAnimationAdapter runner = new RemoteAnimationAdapter( SCREENSHOT_REMOTE_RUNNER, 0, 0); try { WindowManagerGlobal.getWindowManagerService() .overridePendingAppTransitionRemote(runner, DEFAULT_DISPLAY); } catch (Exception e) { Log.e(TAG, "Error overriding screenshot app transition", e); } }, mMainExecutor); }); } catch (CancellationException e) { Loading Loading @@ -883,8 +906,8 @@ public class ScreenshotController { return () -> { Pair<ActivityOptions, ExitTransitionCoordinator> transition = ActivityOptions.startSharedElementAnimation( mWindow, new ScreenshotExitTransitionCallbacks(), null, Pair.create(mScreenshotView.getScreenshotPreview(), mWindow, new ScreenshotExitTransitionCallbacksSupplier(true).get(), null, Pair.create(mScreenshotView.getScreenshotPreview(), ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME)); transition.second.startExit(); Loading Loading @@ -970,7 +993,17 @@ public class ScreenshotController { return matchWithinTolerance; } private class ScreenshotExitTransitionCallbacks implements ExitTransitionCallbacks { private class ScreenshotExitTransitionCallbacksSupplier implements Supplier<ExitTransitionCallbacks> { final boolean mDismissOnHideSharedElements; ScreenshotExitTransitionCallbacksSupplier(boolean dismissOnHideSharedElements) { mDismissOnHideSharedElements = dismissOnHideSharedElements; } @Override public ExitTransitionCallbacks get() { return new ExitTransitionCallbacks() { @Override public boolean isReturnTransitionAllowed() { return false; Loading @@ -978,11 +1011,15 @@ public class ScreenshotController { @Override public void hideSharedElements() { if (mDismissOnHideSharedElements) { finishDismiss(); } } @Override public void onFinish() { } }; } } }
packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotView.java +47 −3 Original line number Diff line number Diff line Loading @@ -764,7 +764,53 @@ public class ScreenshotView extends FrameLayout implements return r; } void startLongScreenshotTransition(Rect destination, Runnable onTransitionEnd, ScrollCaptureController.LongScreenshot longScreenshot) { mScrollablePreview.setImageBitmap(longScreenshot.toBitmap()); ValueAnimator anim = ValueAnimator.ofFloat(0, 1); float startX = mScrollablePreview.getX(); float startY = mScrollablePreview.getY(); int[] locInScreen = mScrollablePreview.getLocationOnScreen(); destination.offset((int) startX - locInScreen[0], (int) startY - locInScreen[1]); mScrollablePreview.setPivotX(0); mScrollablePreview.setPivotY(0); mScrollablePreview.setAlpha(1f); float currentScale = mScrollablePreview.getWidth() / (float) longScreenshot.getWidth(); Matrix matrix = new Matrix(); matrix.setScale(currentScale, currentScale); matrix.postTranslate( longScreenshot.getLeft() * currentScale, longScreenshot.getTop() * currentScale); mScrollablePreview.setImageMatrix(matrix); float destinationScale = destination.width() / (float) mScrollablePreview.getWidth(); anim.addUpdateListener(animation -> { float t = animation.getAnimatedFraction(); mScrollingScrim.setAlpha(1 - t); float currScale = MathUtils.lerp(1, destinationScale, t); mScrollablePreview.setScaleX(currScale); mScrollablePreview.setScaleY(currScale); mScrollablePreview.setX(MathUtils.lerp(startX, destination.left, t)); mScrollablePreview.setY(MathUtils.lerp(startY, destination.top, t)); }); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); onTransitionEnd.run(); mScrollablePreview.animate().alpha(0).setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mCallbacks.onDismiss(); } }); } }); anim.start(); } void prepareScrollingTransition(ScrollCaptureResponse response, Bitmap screenBitmap) { mScrollingScrim.setImageBitmap(screenBitmap); mScrollingScrim.setVisibility(View.VISIBLE); Rect scrollableArea = scrollableAreaOnScreen(response); float scale = mCornerSizeX / (mOrientationPortrait ? screenBitmap.getWidth() : screenBitmap.getHeight()); Loading @@ -775,14 +821,12 @@ public class ScreenshotView extends FrameLayout implements params.height = (int) (scale * scrollableArea.height()); Matrix matrix = new Matrix(); matrix.setScale(scale, scale); matrix.postTranslate(0, -scrollableArea.top * scale); matrix.postTranslate(-scrollableArea.left * scale, -scrollableArea.top * scale); mScrollablePreview.setTranslationX(scale * scrollableArea.left); mScrollablePreview.setTranslationY(scale * scrollableArea.top); mScrollablePreview.setImageMatrix(matrix); mScrollingScrim.setImageBitmap(screenBitmap); mScrollingScrim.setVisibility(View.VISIBLE); mScrollablePreview.setImageBitmap(screenBitmap); mScrollablePreview.setVisibility(View.VISIBLE); createScreenshotFadeDismissAnimation(true).start(); Loading