OSDN Git Service

Tweaking stack shadows and layout.
authorWinson <winsonc@google.com>
Mon, 15 Feb 2016 23:40:08 +0000 (15:40 -0800)
committerWinson <winsonc@google.com>
Tue, 16 Feb 2016 00:42:19 +0000 (16:42 -0800)
- Properly setting view outline alpha
- Ensuring that dismissing while in focused state will return to
  non-focused state
- Fixing mis-calculation with bottom stack area

Change-Id: I281b7707421ffde4225180c63c7d40bf325f7f72

packages/SystemUI/res/values-sw720dp/dimens.xml
packages/SystemUI/res/values/dimens.xml
packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java

index 7cee381..de4a842 100644 (file)
@@ -31,6 +31,8 @@
 
     <!-- The radius of the rounded corners on a task view. -->
     <dimen name="recents_task_view_rounded_corners_radius">3dp</dimen>
+    <!-- The radius of the rounded corners on a task view's shadow. -->
+    <dimen name="recents_task_view_shadow_rounded_corners_radius">18dp</dimen>
 
     <!-- The fraction of the screen height where the clock on the Keyguard has its center. The
      max value is used when no notifications are displaying, and the min value is when the
index f3b9199..216d439 100644 (file)
 
     <!-- The radius of the rounded corners on a task view. -->
     <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
+    <!-- The radius of the rounded corners on a task view's shadow. -->
+    <dimen name="recents_task_view_shadow_rounded_corners_radius">12dp</dimen>
 
     <!-- The min translation in the Z index for the last task. -->
-    <dimen name="recents_task_view_z_min">16dp</dimen>
+    <dimen name="recents_task_view_z_min">3dp</dimen>
 
     <!-- The max translation in the Z index for the last task. -->
-    <dimen name="recents_task_view_z_max">48dp</dimen>
+    <dimen name="recents_task_view_z_max">24dp</dimen>
 
     <!-- The amount to translate when animating the removal of a task. -->
     <dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>
     <!-- The amount to allow the stack to overscroll. -->
     <dimen name="recents_stack_overscroll">24dp</dimen>
 
-    <!-- The size of the peek area at the top of the stack. -->
+    <!-- The size of the peek area at the top of the stack (below the status bar). -->
     <dimen name="recents_layout_focused_top_peek_size">@dimen/recents_history_button_height</dimen>
 
-    <!-- The size of the peek area at the bottom of the stack. -->
-    <dimen name="recents_layout_focused_bottom_peek_size">@dimen/recents_history_button_height</dimen>
+    <!-- The size of each task peek area at the bottom of the stack (above the nav bar). -->
+    <dimen name="recents_layout_focused_bottom_task_peek_size">16dp</dimen>
 
     <!-- The height of the history button. -->
     <dimen name="recents_history_button_height">48dp</dimen>
index 8575c0d..253d06a 100644 (file)
@@ -81,6 +81,13 @@ public class AnimateableViewBounds extends ViewOutlineProvider {
         }
     }
 
+    /**
+     * @return the outline alpha.
+     */
+    public float getAlpha() {
+        return mAlpha;
+    }
+
     /** Sets the top clip. */
     public void setClipTop(int top) {
         mClipRect.top = top;
index d8a3e76..4359101 100644 (file)
@@ -153,6 +153,7 @@ public class FreeformWorkspaceLayoutAlgorithm {
             transformOut.alpha = 1f;
             transformOut.translationZ = stackLayout.mMaxTranslationZ;
             transformOut.dimAlpha = 0f;
+            transformOut.viewOutlineAlpha = TaskStackLayoutAlgorithm.OUTLINE_ALPHA_MAX_VALUE;
             transformOut.rect.set(ffRect);
             transformOut.rect.offset(stackLayout.mFreeformRect.left, stackLayout.mFreeformRect.top);
             transformOut.visible = true;
index 76972d7..890b445 100644 (file)
@@ -458,7 +458,8 @@ public class TaskStackAnimationHelper {
         mStackView.cancelDeferredTaskViewLayoutAnimation();
 
         // Get the final set of task transforms
-        mStackView.getLayoutTaskTransforms(newScroll, stackTasks, mTmpFinalTaskTransforms);
+        mStackView.getLayoutTaskTransforms(newScroll, stackLayout.getFocusState(), stackTasks,
+                mTmpFinalTaskTransforms);
 
         // Focus the task view
         TaskView newFocusedTaskView = mStackView.getChildViewForTask(newFocusedTask);
index 360a139..6be42c3 100644 (file)
@@ -108,8 +108,13 @@ public class TaskStackLayoutAlgorithm {
     // The scale factor to apply to the user movement in the stack to unfocus it
     private static final float UNFOCUS_MULTIPLIER = 0.8f;
 
+    // The distribution of view bounds alpha
+    // XXX: This is a hack because you can currently set the max alpha to be > 1f
+    public static final float OUTLINE_ALPHA_MIN_VALUE = 0f;
+    public static final float OUTLINE_ALPHA_MAX_VALUE = 2f;
+
     // The distribution of dim to apply to tasks in the stack
-    public static final float DIM_MAX_VALUE = 0.35f;
+    private static final float DIM_MAX_VALUE = 0.35f;
     private static final Path UNFOCUSED_DIM_PATH = new Path();
     private static final Path FOCUSED_DIM_PATH = new Path();
     static {
@@ -263,7 +268,7 @@ public class TaskStackLayoutAlgorithm {
     @ViewDebug.ExportedProperty(category="recents")
     private int mFocusedTopPeekHeight;
     @ViewDebug.ExportedProperty(category="recents")
-    private int mFocusedBottomPeekHeight;
+    private int mFocusedBottomTaskPeekHeight;
 
     // The offset from the top of the stack to the top of the bounds when the stack is scrolled to
     // the end
@@ -337,8 +342,8 @@ public class TaskStackLayoutAlgorithm {
         mFocusState = getDefaultFocusState();
         mFocusedTopPeekHeight =
                 res.getDimensionPixelSize(R.dimen.recents_layout_focused_top_peek_size);
-        mFocusedBottomPeekHeight =
-                res.getDimensionPixelSize(R.dimen.recents_layout_focused_bottom_peek_size);
+        mFocusedBottomTaskPeekHeight =
+                res.getDimensionPixelSize(R.dimen.recents_layout_focused_bottom_task_peek_size);
 
         mMinTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
         mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_task_view_z_max);
@@ -607,7 +612,7 @@ public class TaskStackLayoutAlgorithm {
 
             boolean isFrontMostTaskInGroup = task.group == null || task.group.isFrontMostTask(task);
             if (isFrontMostTaskInGroup) {
-                getStackTransform(taskProgress, mInitialScrollP, tmpTransform, null,
+                getStackTransform(taskProgress, mInitialScrollP, mFocusState, tmpTransform, null,
                         false /* ignoreSingleTaskCase */, false /* forceUpdate */);
                 float screenY = tmpTransform.rect.top;
                 boolean hasVisibleThumbnail = (prevScreenY - screenY) > taskBarHeight;
@@ -641,11 +646,11 @@ public class TaskStackLayoutAlgorithm {
      */
     public TaskViewTransform getStackTransform(Task task, float stackScroll,
             TaskViewTransform transformOut, TaskViewTransform frontTransform) {
-        return getStackTransform(task, stackScroll, transformOut, frontTransform,
+        return getStackTransform(task, stackScroll, mFocusState, transformOut, frontTransform,
                 false /* forceUpdate */);
     }
 
-    public TaskViewTransform getStackTransform(Task task, float stackScroll,
+    public TaskViewTransform getStackTransform(Task task, float stackScroll, float focusState,
         TaskViewTransform transformOut, TaskViewTransform frontTransform, boolean forceUpdate) {
         if (mFreeformLayoutAlgorithm.isTransformAvailable(task, this)) {
             mFreeformLayoutAlgorithm.getTransform(task, transformOut, this);
@@ -656,7 +661,7 @@ public class TaskStackLayoutAlgorithm {
                 transformOut.reset();
                 return transformOut;
             }
-            getStackTransform(mTaskIndexMap.get(task.key), stackScroll, transformOut,
+            getStackTransform(mTaskIndexMap.get(task.key), stackScroll, focusState, transformOut,
                     frontTransform, false /* ignoreSingleTaskCase */, forceUpdate);
             return transformOut;
         }
@@ -682,7 +687,7 @@ public class TaskStackLayoutAlgorithm {
      *                             internally to ensure that we can calculate the transform for any
      *                             position in the stack.
      */
-    public void getStackTransform(float taskProgress, float stackScroll,
+    public void getStackTransform(float taskProgress, float stackScroll, float focusState,
             TaskViewTransform transformOut, TaskViewTransform frontTransform,
             boolean ignoreSingleTaskCase, boolean forceUpdate) {
         SystemServicesProxy ssp = Recents.getSystemServices();
@@ -706,6 +711,7 @@ public class TaskStackLayoutAlgorithm {
         int y;
         float z;
         float dimAlpha;
+        float viewOutlineAlpha;
         if (!ssp.hasFreeformWorkspaceSupport() && mNumStackTasks == 1 && !ignoreSingleTaskCase) {
             // When there is exactly one task, then decouple the task from the stack and just move
             // in screen space
@@ -715,6 +721,7 @@ public class TaskStackLayoutAlgorithm {
             y = centerYOffset + getYForDeltaP(tmpP, 0);
             z = mMaxTranslationZ;
             dimAlpha = 0f;
+            viewOutlineAlpha = (OUTLINE_ALPHA_MIN_VALUE + OUTLINE_ALPHA_MAX_VALUE) / 2f;
 
         } else {
             // Otherwise, update the task to the stack layout
@@ -726,16 +733,20 @@ public class TaskStackLayoutAlgorithm {
             float focusedDim = 1f - FOCUSED_DIM_INTERPOLATOR.getInterpolation(focusedRangeX);
 
             y = (mStackRect.top - mTaskRect.top) +
-                    (int) Utilities.mapRange(mFocusState, unfocusedY, focusedY);
-            z = Utilities.clamp01(unfocusedRangeX) * mMaxTranslationZ;
-            dimAlpha = Utilities.mapRange(mFocusState, unfocusedDim, focusedDim);
+                    (int) Utilities.mapRange(focusState, unfocusedY, focusedY);
+            z = Utilities.mapRange(Utilities.clamp01(unfocusedRangeX), mMinTranslationZ,
+                    mMaxTranslationZ);
+            dimAlpha = DIM_MAX_VALUE * Utilities.mapRange(focusState, unfocusedDim, focusedDim);
+            viewOutlineAlpha = Utilities.mapRange(Utilities.clamp01(unfocusedRangeX),
+                    OUTLINE_ALPHA_MIN_VALUE, OUTLINE_ALPHA_MAX_VALUE);
         }
 
         // Fill out the transform
         transformOut.scale = 1f;
         transformOut.alpha = 1f;
         transformOut.translationZ = z;
-        transformOut.dimAlpha = DIM_MAX_VALUE * dimAlpha;
+        transformOut.dimAlpha = dimAlpha;
+        transformOut.viewOutlineAlpha = viewOutlineAlpha;
         transformOut.rect.set(mTaskRect);
         transformOut.rect.offset(x, y);
         Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
@@ -788,8 +799,9 @@ public class TaskStackLayoutAlgorithm {
         // linear pieces that goes from (0,1) through (0.5, peek height offset),
         // (0.5, bottom task offsets), and (1,0).
         float topPeekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height();
-        float bottomPeekHeightPct = (float) Math.max(mFocusedBottomPeekHeight, mStackRect.bottom -
-                mTaskRect.bottom) / mStackRect.height();
+        float bottomPeekHeightPct = Math.max(
+                mSystemInsets.bottom + mFocusedRange.relativeMax * mFocusedBottomTaskPeekHeight,
+                mStackBottomOffset + mFocusedBottomTaskPeekHeight) / mStackRect.height();
         Path p = new Path();
         p.moveTo(0f, 1f);
         p.lineTo(0.5f, 1f - topPeekHeightPct);
@@ -835,10 +847,10 @@ public class TaskStackLayoutAlgorithm {
                 mFocusedRange.relativeMin);
         float max = Utilities.mapRange(mFocusState, mUnfocusedRange.relativeMax,
                 mFocusedRange.relativeMax);
-        getStackTransform(min, 0f, mBackOfStackTransform, null, true /* ignoreSingleTaskCase */,
-                true /* forceUpdate */);
-        getStackTransform(max, 0f, mFrontOfStackTransform, null, true /* ignoreSingleTaskCase */,
-                true /* forceUpdate */);
+        getStackTransform(min, 0f, mFocusState, mBackOfStackTransform, null,
+                true /* ignoreSingleTaskCase */, true /* forceUpdate */);
+        getStackTransform(max, 0f, mFocusState, mFrontOfStackTransform, null,
+                true /* ignoreSingleTaskCase */, true /* forceUpdate */);
         mBackOfStackTransform.visible = true;
         mFrontOfStackTransform.visible = true;
     }
index 2195b5e..0ee9caf 100644 (file)
@@ -665,6 +665,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
     public void getCurrentTaskTransforms(ArrayList<Task> tasks,
             ArrayList<TaskViewTransform> transformsOut) {
         Utilities.matchTaskListSize(tasks, transformsOut);
+        float focusState = mLayoutAlgorithm.getFocusState();
         for (int i = tasks.size() - 1; i >= 0; i--) {
             Task task = tasks.get(i);
             TaskViewTransform transform = transformsOut.get(i);
@@ -673,7 +674,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                 transform.fillIn(tv);
             } else {
                 mLayoutAlgorithm.getStackTransform(task, mStackScroller.getStackScroll(),
-                        transform, null, true /* forceUpdate */);
+                        focusState, transform, null, true /* forceUpdate */);
             }
             transform.visible = true;
         }
@@ -681,15 +682,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
 
     /**
      * Returns the task transforms for all the tasks in the stack if the stack was at the given
-     * {@param stackScroll}.
+     * {@param stackScroll} and {@param focusState}.
      */
-    public void getLayoutTaskTransforms(float stackScroll, ArrayList<Task> tasks,
+    public void getLayoutTaskTransforms(float stackScroll, float focusState, ArrayList<Task> tasks,
             ArrayList<TaskViewTransform> transformsOut) {
         Utilities.matchTaskListSize(tasks, transformsOut);
         for (int i = tasks.size() - 1; i >= 0; i--) {
             Task task = tasks.get(i);
             TaskViewTransform transform = transformsOut.get(i);
-            mLayoutAlgorithm.getStackTransform(task, stackScroll, transform, null,
+            mLayoutAlgorithm.getStackTransform(task, stackScroll, focusState, transform, null,
                     true /* forceUpdate */);
             transform.visible = true;
         }
@@ -1510,7 +1511,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
     /**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/
 
     @Override
-    public void onScrollChanged(float prevScroll, float curScroll, AnimationProps animation) {
+    public void onStackScrollChanged(float prevScroll, float curScroll, AnimationProps animation) {
         mUIDozeTrigger.poke();
         if (animation != null) {
             relayoutTaskViewsOnNextFrame(animation);
index b7ff8bc..333df9d 100644 (file)
@@ -39,7 +39,7 @@ public class TaskStackViewScroller {
     private static final boolean DEBUG = false;
 
     public interface TaskStackViewScrollerCallbacks {
-        void onScrollChanged(float prevScroll, float curScroll, AnimationProps animation);
+        void onStackScrollChanged(float prevScroll, float curScroll, AnimationProps animation);
     }
 
     /**
@@ -106,7 +106,7 @@ public class TaskStackViewScroller {
         float prevStackScroll = mStackScrollP;
         mStackScrollP = s;
         if (mCb != null) {
-            mCb.onScrollChanged(prevStackScroll, mStackScrollP, animation);
+            mCb.onStackScrollChanged(prevStackScroll, mStackScrollP, animation);
         }
     }
 
index b94a9f7..47072ba 100644 (file)
@@ -401,6 +401,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
         mCurrentTasks = mSv.getStack().getStackTasks();
         MutableBoolean isFrontMostTask = new MutableBoolean(false);
         Task anchorTask = mSv.findAnchorTask(mCurrentTasks, isFrontMostTask);
+        TaskStackLayoutAlgorithm layoutAlgorithm = mSv.getStackAlgorithm();
         TaskStackViewScroller stackScroller = mSv.getScroller();
         if (anchorTask != null) {
             // Get the current set of task transforms
@@ -411,7 +412,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
             float prevAnchorTaskScroll = 0;
             boolean pullStackForward = mCurrentTasks.size() > 0;
             if (pullStackForward) {
-                prevAnchorTaskScroll = mSv.getStackAlgorithm().getStackScrollForTask(anchorTask);
+                prevAnchorTaskScroll = layoutAlgorithm.getStackScrollForTask(anchorTask);
             }
 
             // Calculate where the views would be without the deleting tasks
@@ -423,9 +424,9 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
                 newStackScroll = stackScroller.getBoundedStackScroll(newStackScroll);
             } else if (pullStackForward) {
                 // Otherwise, offset the scroll by the movement of the anchor task
-                float anchorTaskScroll = mSv.getStackAlgorithm().getStackScrollForTask(anchorTask);
+                float anchorTaskScroll = layoutAlgorithm.getStackScrollForTask(anchorTask);
                 float stackScrollOffset = (anchorTaskScroll - prevAnchorTaskScroll);
-                if (mSv.getStackAlgorithm().getFocusState() !=
+                if (layoutAlgorithm.getFocusState() !=
                         TaskStackLayoutAlgorithm.STATE_FOCUSED) {
                     // If we are focused, we don't want the front task to move, but otherwise, we
                     // allow the back task to move up, and the front task to move back
@@ -439,7 +440,8 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
             mSv.bindVisibleTaskViews(newStackScroll);
 
             // Get the final set of task transforms (with task removed)
-            mSv.getLayoutTaskTransforms(newStackScroll, mCurrentTasks, mFinalTaskTransforms);
+            mSv.getLayoutTaskTransforms(newStackScroll, TaskStackLayoutAlgorithm.STATE_UNFOCUSED,
+                    mCurrentTasks, mFinalTaskTransforms);
 
             // Set the target to scroll towards upon dismissal
             mTargetStackScroll = newStackScroll;
@@ -448,7 +450,8 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
              * Post condition: All views that will be visible as a part of the gesture are retrieved
              *                 and at their initial positions.  The stack is still at the current
              *                 scroll, but the layout is updated without the task currently being
-             *                 dismissed.
+             *                 dismissed.  The final layout is in the unfocused stack state, which
+             *                 will be applied when the current task is dismissed.
              */
         }
     }
@@ -472,6 +475,8 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
         tv.setTouchEnabled(true);
         // Update the scroll to the final scroll position from onBeginDrag()
         mSv.getScroller().setStackScroll(mTargetStackScroll, null);
+        // Update the focus state to the final focus state
+        mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
         // Remove the task view from the stack
         EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv));
         // Stop tracking this deletion animation
@@ -547,6 +552,9 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
                     fromTransform.rect, toTransform.rect));
             mTmpTransform.dimAlpha = fromTransform.dimAlpha + (toTransform.dimAlpha -
                     fromTransform.dimAlpha) * dismissFraction;
+            mTmpTransform.viewOutlineAlpha = fromTransform.viewOutlineAlpha +
+                    (toTransform.viewOutlineAlpha - fromTransform.viewOutlineAlpha) *
+                            dismissFraction;
             mTmpTransform.translationZ = fromTransform.translationZ +
                     (toTransform.translationZ - fromTransform.translationZ) * dismissFraction;
 
index 972b02a..0c78e6a 100644 (file)
@@ -80,7 +80,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
      * launching) needs to be animated independently of the task progress.
      */
     public static final Property<TaskView, Float> DIM_ALPHA =
-            new FloatProperty<TaskView>("dim") {
+            new FloatProperty<TaskView>("dimAlpha") {
                 @Override
                 public void setValue(TaskView tv, float dimAlpha) {
                     tv.setDimAlpha(dimAlpha);
@@ -92,6 +92,23 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
                 }
             };
 
+    /**
+     * The dim overlay is generally calculated from the task progress, but occasionally (like when
+     * launching) needs to be animated independently of the task progress.
+     */
+    public static final Property<TaskView, Float> VIEW_OUTLINE_ALPHA =
+            new FloatProperty<TaskView>("viewOutlineAlpha") {
+                @Override
+                public void setValue(TaskView tv, float alpha) {
+                    tv.getViewBounds().setAlpha(alpha);
+                }
+
+                @Override
+                public Float get(TaskView tv) {
+                    return tv.getViewBounds().getAlpha();
+                }
+            };
+
     @ViewDebug.ExportedProperty(category="recents")
     float mDimAlpha;
     PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP);
@@ -144,7 +161,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
         RecentsConfiguration config = Recents.getConfiguration();
         Resources res = context.getResources();
         mViewBounds = new AnimateableViewBounds(this, res.getDimensionPixelSize(
-                R.dimen.recents_task_view_rounded_corners_radius));
+                R.dimen.recents_task_view_shadow_rounded_corners_radius));
         if (config.fakeShadows) {
             setBackground(new FakeShadowDrawable(res, config));
         }
@@ -251,6 +268,9 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
             if (Float.compare(getDimAlpha(), toTransform.dimAlpha) != 0) {
                 setDimAlpha(toTransform.dimAlpha);
             }
+            if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
+                mViewBounds.setAlpha(toTransform.viewOutlineAlpha);
+            }
             // Manually call back to the animator listener and update callback
             if (toAnimation.getListener() != null) {
                 toAnimation.getListener().onAnimationEnd(null);
@@ -265,6 +285,11 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
                         toTransform.dimAlpha);
                 mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, anim));
             }
+            if (Float.compare(mViewBounds.getAlpha(), toTransform.viewOutlineAlpha) != 0) {
+                ObjectAnimator anim = ObjectAnimator.ofFloat(this, VIEW_OUTLINE_ALPHA,
+                        mViewBounds.getAlpha(), toTransform.viewOutlineAlpha);
+                mTmpAnimators.add(toAnimation.apply(AnimationProps.BOUNDS, anim));
+            }
             if (updateCallback != null) {
                 ValueAnimator updateCallbackAnim = ValueAnimator.ofInt(0, 1);
                 updateCallbackAnim.addUpdateListener(updateCallback);
@@ -367,7 +392,6 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
 
         int dimAlphaInt = (int) (dimAlpha * 255);
         mDimAlpha = dimAlpha;
-        mViewBounds.setAlpha(1f - (dimAlpha / TaskStackLayoutAlgorithm.DIM_MAX_VALUE));
         if (config.useHardwareLayers) {
             // Defer setting hardware layers if we have not yet measured, or there is no dim to draw
             if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0) {
index d3d2dbe..0d16a79 100644 (file)
@@ -87,6 +87,7 @@ public class TaskViewTransform {
     public float scale = 1f;
     public float alpha = 1f;
     public float dimAlpha = 0f;
+    public float viewOutlineAlpha = 0f;
 
     public boolean visible = false;
 
@@ -102,6 +103,7 @@ public class TaskViewTransform {
         alpha = tv.getAlpha();
         visible = true;
         dimAlpha = tv.getDimAlpha();
+        viewOutlineAlpha = tv.getViewBounds().getAlpha();
         rect.set(tv.getLeft(), tv.getTop(), tv.getRight(), tv.getBottom());
     }
 
@@ -114,6 +116,7 @@ public class TaskViewTransform {
         alpha = other.alpha;
         visible = other.visible;
         dimAlpha = other.dimAlpha;
+        viewOutlineAlpha = other.viewOutlineAlpha;
         rect.set(other.rect);
     }
 
@@ -125,6 +128,7 @@ public class TaskViewTransform {
         scale = 1f;
         alpha = 1f;
         dimAlpha = 0f;
+        viewOutlineAlpha = 0f;
         visible = false;
         rect.setEmpty();
     }