diff options
| -rw-r--r-- | core/java/android/view/animation/ClipRectTBAnimation.java | 49 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/AppTransition.java | 138 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/DockedStackDividerController.java | 23 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java | 6 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/animation/ClipRectLRAnimation.java (renamed from core/java/android/view/animation/ClipRectLRAnimation.java) | 8 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java | 86 |
6 files changed, 210 insertions, 100 deletions
diff --git a/core/java/android/view/animation/ClipRectTBAnimation.java b/core/java/android/view/animation/ClipRectTBAnimation.java deleted file mode 100644 index 06f86ceda82f..000000000000 --- a/core/java/android/view/animation/ClipRectTBAnimation.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.view.animation; - -import android.graphics.Rect; - -/** - * Special case of ClipRectAnimation that animates only the top/bottom - * dimensions of the clip, picking up the other dimensions from whatever is - * set on the transform already. - * - * @hide - */ -public class ClipRectTBAnimation extends ClipRectAnimation { - - /** - * Constructor. Passes in 0 for Left/Right parameters of ClipRectAnimation - */ - public ClipRectTBAnimation(int fromT, int fromB, int toT, int toB) { - super(0, fromT, 0, fromB, 0, toT, 0, toB); - } - - /** - * Calculates and sets clip rect on given transformation. It uses existing values - * on the Transformation for Left/Right clip parameters. - */ - @Override - protected void applyTransformation(float it, Transformation tr) { - Rect oldClipRect = tr.getClipRect(); - tr.setClipRect(oldClipRect.left, mFromRect.top + (int) ((mToRect.top - mFromRect.top) * it), - oldClipRect.right, - mFromRect.bottom + (int) ((mToRect.bottom - mFromRect.bottom) * it)); - } - -} diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index ad12c66d6ccb..ba9e6404cf66 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -46,7 +46,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.Nullable; import android.content.Context; -import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Rect; import android.os.Debug; @@ -64,8 +63,6 @@ import android.view.animation.Animation; import android.view.animation.AnimationSet; import android.view.animation.AnimationUtils; import android.view.animation.ClipRectAnimation; -import android.view.animation.ClipRectLRAnimation; -import android.view.animation.ClipRectTBAnimation; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; import android.view.animation.ScaleAnimation; @@ -74,10 +71,11 @@ import android.view.animation.TranslateAnimation; import com.android.internal.util.DumpUtils.Dump; import com.android.server.AttributeCache; import com.android.server.wm.WindowManagerService.H; +import com.android.server.wm.animation.ClipRectLRAnimation; +import com.android.server.wm.animation.ClipRectTBAnimation; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -136,6 +134,16 @@ public class AppTransition implements Dump { private static final float RECENTS_THUMBNAIL_FADEOUT_FRACTION = 0.5f; static final int DEFAULT_APP_TRANSITION_DURATION = 336; + + /** Interpolator to be used for animations that respond directly to a touch */ + static final Interpolator TOUCH_RESPONSE_INTERPOLATOR = + new PathInterpolator(0.3f, 0f, 0.1f, 1f); + + /** + * Maximum duration for the clip reveal animation. This is used when there is a lot of movement + * involved, to make it more understandable. + */ + private static final int MAX_CLIP_REVEAL_TRANSITION_DURATION = 420; private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336; private static final int THUMBNAIL_APP_TRANSITION_ALPHA_DURATION = 336; private static final long APP_TRANSITION_TIMEOUT_MS = 5000; @@ -200,13 +208,10 @@ public class AppTransition implements Dump { private final Interpolator mFastOutLinearInInterpolator; private final Interpolator mClipHorizontalInterpolator = new PathInterpolator(0, 0, 0.4f, 1f); - /** Interpolator to be used for animations that respond directly to a touch */ - private final Interpolator mTouchResponseInterpolator = - new PathInterpolator(0.3f, 0f, 0.1f, 1f); - private final int mClipRevealTranslationY; private int mCurrentUserId = 0; + private long mLastClipRevealTransitionDuration = DEFAULT_APP_TRANSITION_DURATION; private final ArrayList<AppTransitionListener> mListeners = new ArrayList<>(); private final ExecutorService mDefaultExecutor = Executors.newSingleThreadExecutor(); @@ -636,50 +641,101 @@ public class AppTransition implements Dump { bitmap, new Rect(left, top, left + width, top + height)); } - private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame) { + long getLastClipRevealTransitionDuration() { + return mLastClipRevealTransitionDuration; + } + + /** + * Calculates the duration for the clip reveal animation. If the clip is "cut off", meaning that + * the start rect is outside of the target rect, and there is a lot of movement going on. + * + * @param cutOff whether the start rect was not fully contained by the end rect + * @param translationX the total translation the surface moves in x direction + * @param translationY the total translation the surfaces moves in y direction + * @param displayFrame our display frame + * + * @return the duration of the clip reveal animation, in milliseconds + */ + private long calculateClipRevealTransitionDuration(boolean cutOff, float translationX, + float translationY, Rect displayFrame) { + if (!cutOff) { + return DEFAULT_APP_TRANSITION_DURATION; + } + final float fraction = Math.max(Math.abs(translationX) / displayFrame.width(), + Math.abs(translationY) / displayFrame.height()); + return (long) (DEFAULT_APP_TRANSITION_DURATION + fraction * + (MAX_CLIP_REVEAL_TRANSITION_DURATION - DEFAULT_APP_TRANSITION_DURATION)); + } + + private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame, + Rect displayFrame) { final Animation anim; if (enter) { - // Reveal will expand and move faster in horizontal direction - final int appWidth = appFrame.width(); final int appHeight = appFrame.height(); + // mTmpRect will contain an area around the launcher icon that was pressed. We will // clip reveal from that area in the final area of the app. getDefaultNextAppTransitionStartRect(mTmpRect); float t = 0f; if (appHeight > 0) { - t = (float) mTmpRect.left / appHeight; + t = (float) mTmpRect.top / displayFrame.height(); } - int translationY = mClipRevealTranslationY + (int)(appHeight / 7f * t); - + int translationY = mClipRevealTranslationY + (int)(displayFrame.height() / 7f * t); + int translationX = 0; + int translationYCorrection = translationY; int centerX = mTmpRect.centerX(); int centerY = mTmpRect.centerY(); int halfWidth = mTmpRect.width() / 2; int halfHeight = mTmpRect.height() / 2; + int clipStartX = centerX - halfWidth - appFrame.left; + int clipStartY = centerY - halfHeight - appFrame.top; + boolean cutOff = false; + + // If the starting rectangle is fully or partially outside of the target rectangle, we + // need to start the clipping at the edge and then achieve the rest with translation + // and extending the clip rect from that edge. + if (appFrame.top > centerY - halfHeight) { + translationY = (centerY - halfHeight) - appFrame.top; + translationYCorrection = 0; + clipStartY = 0; + cutOff = true; + } + if (appFrame.left > centerX - halfWidth) { + translationX = (centerX - halfWidth) - appFrame.left; + clipStartX = 0; + cutOff = true; + } + if (appFrame.right < centerX + halfWidth) { + translationX = (centerX + halfWidth) - appFrame.right; + clipStartX = appWidth - mTmpRect.width(); + cutOff = true; + } + final long duration = calculateClipRevealTransitionDuration(cutOff, translationX, + translationY, displayFrame); // Clip third of the from size of launch icon, expand to full width/height Animation clipAnimLR = new ClipRectLRAnimation( - centerX - halfWidth, centerX + halfWidth, 0, appWidth); + clipStartX, clipStartX + mTmpRect.width(), 0, appWidth); clipAnimLR.setInterpolator(mClipHorizontalInterpolator); - clipAnimLR.setDuration((long) (DEFAULT_APP_TRANSITION_DURATION / 2.5f)); - - Animation clipAnimTB = new ClipRectTBAnimation(centerY - halfHeight - translationY, - centerY + halfHeight/ 2 - translationY, 0, appHeight); - clipAnimTB.setInterpolator(mTouchResponseInterpolator); - clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION); - - // We might be animating entrance of a docked task, so we need the translate to account - // for the app frame in which the window will reside. Every other calculation here - // is performed as if the window started at 0,0. - translationY -= appFrame.top; - TranslateAnimation translate = new TranslateAnimation(-appFrame.left, 0, translationY, - 0); - translate.setInterpolator(mLinearOutSlowInInterpolator); - translate.setDuration(DEFAULT_APP_TRANSITION_DURATION); + clipAnimLR.setDuration((long) (duration / 2.5f)); + + TranslateAnimation translate = new TranslateAnimation(translationX, 0, translationY, 0); + translate.setInterpolator(cutOff ? TOUCH_RESPONSE_INTERPOLATOR + : mLinearOutSlowInInterpolator); + translate.setDuration(duration); + + Animation clipAnimTB = new ClipRectTBAnimation( + clipStartY, clipStartY + mTmpRect.height(), + 0, appHeight, + translationYCorrection, 0, + mLinearOutSlowInInterpolator); + clipAnimTB.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR); + clipAnimTB.setDuration(duration); // Quick fade-in from icon to app window - final int alphaDuration = DEFAULT_APP_TRANSITION_DURATION / 4; + final long alphaDuration = duration / 4; AlphaAnimation alpha = new AlphaAnimation(0.5f, 1); alpha.setDuration(alphaDuration); alpha.setInterpolator(mLinearOutSlowInInterpolator); @@ -692,6 +748,7 @@ public class AppTransition implements Dump { set.setZAdjustment(Animation.ZORDER_TOP); set.initialize(appWidth, appHeight, appWidth, appHeight); anim = set; + mLastClipRevealTransitionDuration = duration; } else { final long duration; switch (transit) { @@ -798,7 +855,7 @@ public class AppTransition implements Dump { // Animation up from the thumbnail to the full screen Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW, mTmpRect.left + (thumbWidth / 2f), mTmpRect.top + (thumbHeight / 2f)); - scale.setInterpolator(mTouchResponseInterpolator); + scale.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR); scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION); Animation alpha = new AlphaAnimation(1f, 0f); alpha.setInterpolator(mThumbnailFadeOutInterpolator); @@ -806,7 +863,7 @@ public class AppTransition implements Dump { final float toX = appRect.left + appRect.width() / 2 - (mTmpRect.left + thumbWidth / 2); Animation translate = new TranslateAnimation(0, toX, 0, toY); - translate.setInterpolator(mTouchResponseInterpolator); + translate.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR); translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION); // This AnimationSet uses the Interpolators assigned above. @@ -819,7 +876,7 @@ public class AppTransition implements Dump { // Animation down from the full screen to the thumbnail Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f, mTmpRect.left + (thumbWidth / 2f), mTmpRect.top + (thumbHeight / 2f)); - scale.setInterpolator(mTouchResponseInterpolator); + scale.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR); scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION); Animation alpha = new AlphaAnimation(0f, 1f); alpha.setInterpolator(mThumbnailFadeInInterpolator); @@ -827,7 +884,7 @@ public class AppTransition implements Dump { final float toX = appRect.left + appRect.width() / 2 - (mTmpRect.left + thumbWidth / 2); Animation translate = new TranslateAnimation(toX, 0, toY, 0); - translate.setInterpolator(mTouchResponseInterpolator); + translate.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR); translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION); // This AnimationSet uses the Interpolators assigned above. @@ -839,7 +896,7 @@ public class AppTransition implements Dump { } return prepareThumbnailAnimationWithDuration(a, appWidth, appRect.height(), 0, - mTouchResponseInterpolator); + TOUCH_RESPONSE_INTERPOLATOR); } /** @@ -971,7 +1028,7 @@ public class AppTransition implements Dump { int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION, THUMBNAIL_APP_TRANSITION_DURATION); return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration, - mTouchResponseInterpolator); + TOUCH_RESPONSE_INTERPOLATOR); } private Animation createAspectScaledThumbnailEnterFreeformAnimationLocked(Rect frame, @@ -1223,8 +1280,9 @@ public class AppTransition implements Dump { * bigger. */ Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter, - int orientation, Rect frame, Rect insets, @Nullable Rect surfaceInsets, - boolean isVoiceInteraction, boolean freeform, int taskId) { + int orientation, Rect frame, Rect displayFrame, Rect insets, + @Nullable Rect surfaceInsets, boolean isVoiceInteraction, boolean freeform, + int taskId) { Animation a; if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN || transit == TRANSIT_TASK_OPEN @@ -1269,7 +1327,7 @@ public class AppTransition implements Dump { + " transit=" + appTransitionToString(transit) + " Callers=" + Debug.getCallers(3)); } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) { - a = createClipRevealAnimationLocked(transit, enter, frame); + a = createClipRevealAnimationLocked(transit, enter, frame, displayFrame); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL" diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index ec99d1fd0c9b..d7c1b328ad2d 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -28,6 +28,7 @@ import android.view.IDockedStackListener; import android.view.SurfaceControl; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; +import android.view.animation.PathInterpolator; import com.android.server.wm.DimLayer.DimLayerUser; @@ -39,6 +40,8 @@ import static android.view.WindowManager.DOCKED_BOTTOM; import static android.view.WindowManager.DOCKED_LEFT; import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.DOCKED_TOP; +import static com.android.server.wm.AppTransition.DEFAULT_APP_TRANSITION_DURATION; +import static com.android.server.wm.AppTransition.TOUCH_RESPONSE_INTERPOLATOR; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -49,8 +52,6 @@ public class DockedStackDividerController implements DimLayerUser { private static final String TAG = TAG_WITH_CLASS_NAME ? "DockedStackDividerController" : TAG_WM; - private static final long MINIMIZED_DOCK_ANIMATION_DURATION = 400; - private final WindowManagerService mService; private final DisplayContent mDisplayContent; private final int mDividerWindowWidth; @@ -71,6 +72,7 @@ public class DockedStackDividerController implements DimLayerUser { private long mAnimationStartTime; private float mAnimationStart; private float mAnimationTarget; + private long mAnimationDuration; private final Interpolator mMinimizedDockInterpolator; DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) { @@ -331,6 +333,10 @@ public class DockedStackDividerController implements DimLayerUser { notifyDockedStackMinimizedChanged(minimized, 0); } + private boolean isAnimationMaximizing() { + return mAnimationTarget == 0f; + } + public boolean animate(long now) { if (!mAnimating) { return false; @@ -339,12 +345,17 @@ public class DockedStackDividerController implements DimLayerUser { if (!mAnimationStarted) { mAnimationStarted = true; mAnimationStartTime = now; + final long transitionDuration = isAnimationMaximizing() + ? mService.mAppTransition.getLastClipRevealTransitionDuration() + : DEFAULT_APP_TRANSITION_DURATION; + mAnimationDuration = (long) + (transitionDuration * mService.getTransitionAnimationScaleLocked()); notifyDockedStackMinimizedChanged(mMinimizedDock, - MINIMIZED_DOCK_ANIMATION_DURATION); + mAnimationDuration); } - float t = Math.min(1f, (float) (now - mAnimationStartTime) - / MINIMIZED_DOCK_ANIMATION_DURATION); - t = mMinimizedDockInterpolator.getInterpolation(t); + float t = Math.min(1f, (float) (now - mAnimationStartTime) / mAnimationDuration); + t = (isAnimationMaximizing() ? TOUCH_RESPONSE_INTERPOLATOR : mMinimizedDockInterpolator) + .getInterpolation(t); final TaskStack stack = mDisplayContent.getDockedStackVisibleForUserLocked(); if (stack != null) { final float amount = t * mAnimationTarget + (1 - t) * mAnimationStart; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b41ff1ca278f..882ac57b124b 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2968,6 +2968,8 @@ public class WindowManagerService extends IWindowManager.Stub // Determine the visible rect to calculate the thumbnail clip final WindowState win = atoken.findMainWindow(); final Rect frame = new Rect(0, 0, width, height); + final Rect displayFrame = new Rect(0, 0, + displayInfo.logicalWidth, displayInfo.logicalHeight); final Rect insets = new Rect(); Rect surfaceInsets = null; final boolean freeform = win != null && win.inFreeformWorkspace(); @@ -2995,8 +2997,8 @@ public class WindowManagerService extends IWindowManager.Stub + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets); Animation a = mAppTransition.loadAnimation(lp, transit, enter, - mCurConfiguration.orientation, frame, insets, surfaceInsets, isVoiceInteraction, - freeform, atoken.mTask.mTaskId); + mCurConfiguration.orientation, frame, displayFrame, insets, surfaceInsets, + isVoiceInteraction, freeform, atoken.mTask.mTaskId); if (a != null) { if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + atoken); final int containingWidth = frame.width(); diff --git a/core/java/android/view/animation/ClipRectLRAnimation.java b/services/core/java/com/android/server/wm/animation/ClipRectLRAnimation.java index 8993cd3a2753..0db4c70e2761 100644 --- a/core/java/android/view/animation/ClipRectLRAnimation.java +++ b/services/core/java/com/android/server/wm/animation/ClipRectLRAnimation.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 The Android Open Source Project + * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,12 +11,14 @@ * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and - * limitations under the License. + * limitations under the License */ -package android.view.animation; +package com.android.server.wm.animation; import android.graphics.Rect; +import android.view.animation.ClipRectAnimation; +import android.view.animation.Transformation; /** * Special case of ClipRectAnimation that animates only the left/right diff --git a/services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java b/services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java new file mode 100644 index 000000000000..1f5b1a3f9660 --- /dev/null +++ b/services/core/java/com/android/server/wm/animation/ClipRectTBAnimation.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.wm.animation; + +import android.graphics.Rect; +import android.view.animation.ClipRectAnimation; +import android.view.animation.Interpolator; +import android.view.animation.Transformation; +import android.view.animation.TranslateAnimation; + +/** + * Special case of ClipRectAnimation that animates only the top/bottom + * dimensions of the clip, picking up the other dimensions from whatever is + * set on the transform already. In addition to that, information about a vertical translation + * animation can be specified so this animation simulates as the clip would be applied after instead + * of before applying the translation. + */ +public class ClipRectTBAnimation extends ClipRectAnimation { + + private final int mFromTranslateY; + private final int mToTranslateY; + private final Interpolator mTranslateInterpolator; + private float mNormalizedTime; + + /** + * Constructor. Passes in 0 for Left/Right parameters of ClipRectAnimation + */ + public ClipRectTBAnimation(int fromT, int fromB, int toT, int toB, + int fromTranslateY, int toTranslateY, Interpolator translateInterpolator) { + super(0, fromT, 0, fromB, 0, toT, 0, toB); + mFromTranslateY = fromTranslateY; + mToTranslateY = toTranslateY; + mTranslateInterpolator = translateInterpolator; + } + + @Override + public boolean getTransformation(long currentTime, Transformation outTransformation) { + + // Hack: Because translation animation has a different interpolator, we need to duplicate + // code from Animation here and use it to calculate/store the uninterpolated normalized + // time. + final long startOffset = getStartOffset(); + final long duration = getDuration(); + float normalizedTime; + if (duration != 0) { + normalizedTime = ((float) (currentTime - (getStartTime() + startOffset))) / + (float) duration; + } else { + // time is a step-change with a zero duration + normalizedTime = currentTime < getStartTime() ? 0.0f : 1.0f; + } + mNormalizedTime = normalizedTime; + return super.getTransformation(currentTime, outTransformation); + } + + /** + * Calculates and sets clip rect on given transformation. It uses existing values + * on the Transformation for Left/Right clip parameters. + */ + @Override + protected void applyTransformation(float it, Transformation tr) { + float translationT = mTranslateInterpolator.getInterpolation(mNormalizedTime); + int translation = + (int) (mFromTranslateY + (mToTranslateY - mFromTranslateY) * translationT); + Rect oldClipRect = tr.getClipRect(); + tr.setClipRect(oldClipRect.left, + mFromRect.top - translation + (int) ((mToRect.top - mFromRect.top) * it), + oldClipRect.right, + mFromRect.bottom - translation + (int) ((mToRect.bottom - mFromRect.bottom) * it)); + } + +} |