Loading packages/SystemUI/res/values/ids.xml +4 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,10 @@ <item type="id" name="notification_screenshot"/> <item type="id" name="notification_hidden"/> <item type="id" name="notification_volumeui"/> <item type="id" name="transformation_start_x_tag"/> <item type="id" name="transformation_start_y_tag"/> <item type="id" name="transformation_start_scale_x_tag"/> <item type="id" name="transformation_start_scale_y_tag"/> <!-- Whether the icon is from a notification for which targetSdk < L --> <item type="id" name="icon_is_pre_L"/> Loading packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java +39 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.statusbar; import android.view.View; import com.android.systemui.Interpolators; import com.android.systemui.statusbar.stack.StackStateAnimator; /** * A helper to fade views in and out. Loading @@ -44,7 +45,34 @@ public class CrossFadeHelper { if (view.hasOverlappingRendering()) { view.animate().withLayer(); } } public static void fadeOut(View view, float fadeOutAmount) { view.animate().cancel(); if (fadeOutAmount == 1.0f) { view.setVisibility(View.INVISIBLE); } else if (view.getVisibility() == View.INVISIBLE) { view.setVisibility(View.VISIBLE); } fadeOutAmount = mapToFadeDuration(fadeOutAmount); float alpha = Interpolators.ALPHA_OUT.getInterpolation(1.0f - fadeOutAmount); view.setAlpha(alpha); updateLayerType(view, alpha); } private static float mapToFadeDuration(float fadeOutAmount) { // Assuming a linear interpolator, we can easily map it to our new duration float endPoint = (float) ANIMATION_DURATION_LENGTH / (float) StackStateAnimator.ANIMATION_DURATION_STANDARD; return Math.min(fadeOutAmount / endPoint, 1.0f); } private static void updateLayerType(View view, float alpha) { if (view.hasOverlappingRendering() && alpha > 0.0f && alpha < 1.0f) { view.setLayerType(View.LAYER_TYPE_HARDWARE, null); } else if (view.getLayerType() == View.LAYER_TYPE_HARDWARE) { view.setLayerType(View.LAYER_TYPE_NONE, null); } } public static void fadeIn(final View view) { Loading @@ -62,4 +90,15 @@ public class CrossFadeHelper { view.animate().withLayer(); } } public static void fadeIn(View view, float fadeInAmount) { view.animate().cancel(); if (view.getVisibility() == View.INVISIBLE) { view.setVisibility(View.VISIBLE); } fadeInAmount = mapToFadeDuration(fadeInAmount); float alpha = Interpolators.ALPHA_IN.getInterpolation(fadeInAmount); view.setAlpha(alpha); updateLayerType(view, alpha); } } packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +1 −0 Original line number Diff line number Diff line Loading @@ -868,6 +868,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public void setUserLocked(boolean userLocked) { mUserLocked = userLocked; mPrivateLayout.setUserExpanding(userLocked); } /** Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +67 −2 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public class NotificationContentView extends FrameLayout { private static final int VISIBLE_TYPE_EXPANDED = 1; private static final int VISIBLE_TYPE_HEADSUP = 2; private static final int VISIBLE_TYPE_SINGLELINE = 3; private static final int UNDEFINED = -1; private final Rect mClipBounds = new Rect(); private final int mMinContractedHeight; Loading Loading @@ -102,6 +103,8 @@ public class NotificationContentView extends FrameLayout { private boolean mExpandable; private boolean mClipToActualHeight = true; private ExpandableNotificationRow mContainingNotification; private int mTransformationStartVisibleType; private boolean mUserExpanding; public NotificationContentView(Context context, AttributeSet attrs) { super(context, attrs); Loading Loading @@ -349,6 +352,41 @@ public class NotificationContentView extends FrameLayout { invalidateOutline(); } private void updateContentTransformation() { int visibleType = calculateVisibleType(); if (visibleType != mVisibleType) { // A new transformation starts mTransformationStartVisibleType = mVisibleType; final TransformableView shownView = getTransformableViewForVisibleType(visibleType); final TransformableView hiddenView = getTransformableViewForVisibleType( mTransformationStartVisibleType); shownView.transformFrom(hiddenView, 0.0f); getViewForVisibleType(visibleType).setVisibility(View.VISIBLE); hiddenView.transformTo(shownView, 0.0f); mVisibleType = visibleType; } if (mTransformationStartVisibleType != UNDEFINED && mVisibleType != mTransformationStartVisibleType) { final TransformableView shownView = getTransformableViewForVisibleType(mVisibleType); final TransformableView hiddenView = getTransformableViewForVisibleType( mTransformationStartVisibleType); float transformationAmount = calculateTransformationAmount(); shownView.transformFrom(hiddenView, transformationAmount); hiddenView.transformTo(shownView, transformationAmount); } else { updateViewVisibilities(visibleType); } } private float calculateTransformationAmount() { int startHeight = getViewForVisibleType(mTransformationStartVisibleType).getHeight(); int endHeight = getViewForVisibleType(mVisibleType).getHeight(); int progress = Math.abs(mContentHeight - startHeight); int totalDistance = Math.abs(endHeight - startHeight); float amount = (float) progress / (float) totalDistance; return Math.min(1.0f, amount); } public int getContentHeight() { return mContentHeight; } Loading Loading @@ -397,6 +435,10 @@ public class NotificationContentView extends FrameLayout { if (mContractedChild == null) { return; } if (mUserExpanding) { updateContentTransformation(); return; } int visibleType = calculateVisibleType(); if (visibleType != mVisibleType || force) { if (animate && ((visibleType == VISIBLE_TYPE_EXPANDED && mExpandedChild != null) Loading Loading @@ -492,9 +534,21 @@ public class NotificationContentView extends FrameLayout { * @return one of the static enum types in this view, calculated form the current state */ private int calculateVisibleType() { boolean noExpandedChild = mExpandedChild == null; if (mUserExpanding) { int expandedVisualType = getVisualTypeForHeight( mContainingNotification.getMaxExpandHeight()); int collapsedVisualType = getVisualTypeForHeight( mContainingNotification.getMinExpandHeight()); return mTransformationStartVisibleType == collapsedVisualType ? expandedVisualType : collapsedVisualType; } int viewHeight = Math.min(mContentHeight, mContainingNotification.getIntrinsicHeight()); return getVisualTypeForHeight(viewHeight); } private int getVisualTypeForHeight(float viewHeight) { boolean noExpandedChild = mExpandedChild == null; if (!noExpandedChild && viewHeight == mExpandedChild.getHeight()) { return VISIBLE_TYPE_EXPANDED; } Loading Loading @@ -723,4 +777,15 @@ public class NotificationContentView extends FrameLayout { updateSingleLineView(); } } public void setUserExpanding(boolean userExpanding) { mUserExpanding = userExpanding; if (userExpanding) { mTransformationStartVisibleType = mVisibleType; } else { mTransformationStartVisibleType = UNDEFINED; mVisibleType = calculateVisibleType(); updateViewVisibilities(mVisibleType); } } } packages/SystemUI/src/com/android/systemui/statusbar/TransformableView.java +20 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ public interface TransformableView { /** * Get the current state of a view in a transform animation * * @param fadingView which view we are interested in * @return the current transform state of this viewtype */ Loading @@ -37,18 +38,37 @@ public interface TransformableView { /** * Transform to the given view * * @param notification the view to transform to */ void transformTo(TransformableView notification, Runnable endRunnable); /** * Transform to the given view by a specified amount. * * @param notification the view to transform to * @param transformationAmount how much transformation should be done */ void transformTo(TransformableView notification, float transformationAmount); /** * Transform to this view from the given view * * @param notification the view to transform from */ void transformFrom(TransformableView notification); /** * Transform to this view from the given view by a specified amount. * * @param notification the view to transform from * @param transformationAmount how much transformation should be done */ void transformFrom(TransformableView notification, float transformationAmount); /** * Set this view to be fully visible or gone * * @param visible */ void setVisible(boolean visible); Loading Loading
packages/SystemUI/res/values/ids.xml +4 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,10 @@ <item type="id" name="notification_screenshot"/> <item type="id" name="notification_hidden"/> <item type="id" name="notification_volumeui"/> <item type="id" name="transformation_start_x_tag"/> <item type="id" name="transformation_start_y_tag"/> <item type="id" name="transformation_start_scale_x_tag"/> <item type="id" name="transformation_start_scale_y_tag"/> <!-- Whether the icon is from a notification for which targetSdk < L --> <item type="id" name="icon_is_pre_L"/> Loading
packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java +39 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.systemui.statusbar; import android.view.View; import com.android.systemui.Interpolators; import com.android.systemui.statusbar.stack.StackStateAnimator; /** * A helper to fade views in and out. Loading @@ -44,7 +45,34 @@ public class CrossFadeHelper { if (view.hasOverlappingRendering()) { view.animate().withLayer(); } } public static void fadeOut(View view, float fadeOutAmount) { view.animate().cancel(); if (fadeOutAmount == 1.0f) { view.setVisibility(View.INVISIBLE); } else if (view.getVisibility() == View.INVISIBLE) { view.setVisibility(View.VISIBLE); } fadeOutAmount = mapToFadeDuration(fadeOutAmount); float alpha = Interpolators.ALPHA_OUT.getInterpolation(1.0f - fadeOutAmount); view.setAlpha(alpha); updateLayerType(view, alpha); } private static float mapToFadeDuration(float fadeOutAmount) { // Assuming a linear interpolator, we can easily map it to our new duration float endPoint = (float) ANIMATION_DURATION_LENGTH / (float) StackStateAnimator.ANIMATION_DURATION_STANDARD; return Math.min(fadeOutAmount / endPoint, 1.0f); } private static void updateLayerType(View view, float alpha) { if (view.hasOverlappingRendering() && alpha > 0.0f && alpha < 1.0f) { view.setLayerType(View.LAYER_TYPE_HARDWARE, null); } else if (view.getLayerType() == View.LAYER_TYPE_HARDWARE) { view.setLayerType(View.LAYER_TYPE_NONE, null); } } public static void fadeIn(final View view) { Loading @@ -62,4 +90,15 @@ public class CrossFadeHelper { view.animate().withLayer(); } } public static void fadeIn(View view, float fadeInAmount) { view.animate().cancel(); if (view.getVisibility() == View.INVISIBLE) { view.setVisibility(View.VISIBLE); } fadeInAmount = mapToFadeDuration(fadeInAmount); float alpha = Interpolators.ALPHA_IN.getInterpolation(fadeInAmount); view.setAlpha(alpha); updateLayerType(view, alpha); } }
packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +1 −0 Original line number Diff line number Diff line Loading @@ -868,6 +868,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public void setUserLocked(boolean userLocked) { mUserLocked = userLocked; mPrivateLayout.setUserExpanding(userLocked); } /** Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +67 −2 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ public class NotificationContentView extends FrameLayout { private static final int VISIBLE_TYPE_EXPANDED = 1; private static final int VISIBLE_TYPE_HEADSUP = 2; private static final int VISIBLE_TYPE_SINGLELINE = 3; private static final int UNDEFINED = -1; private final Rect mClipBounds = new Rect(); private final int mMinContractedHeight; Loading Loading @@ -102,6 +103,8 @@ public class NotificationContentView extends FrameLayout { private boolean mExpandable; private boolean mClipToActualHeight = true; private ExpandableNotificationRow mContainingNotification; private int mTransformationStartVisibleType; private boolean mUserExpanding; public NotificationContentView(Context context, AttributeSet attrs) { super(context, attrs); Loading Loading @@ -349,6 +352,41 @@ public class NotificationContentView extends FrameLayout { invalidateOutline(); } private void updateContentTransformation() { int visibleType = calculateVisibleType(); if (visibleType != mVisibleType) { // A new transformation starts mTransformationStartVisibleType = mVisibleType; final TransformableView shownView = getTransformableViewForVisibleType(visibleType); final TransformableView hiddenView = getTransformableViewForVisibleType( mTransformationStartVisibleType); shownView.transformFrom(hiddenView, 0.0f); getViewForVisibleType(visibleType).setVisibility(View.VISIBLE); hiddenView.transformTo(shownView, 0.0f); mVisibleType = visibleType; } if (mTransformationStartVisibleType != UNDEFINED && mVisibleType != mTransformationStartVisibleType) { final TransformableView shownView = getTransformableViewForVisibleType(mVisibleType); final TransformableView hiddenView = getTransformableViewForVisibleType( mTransformationStartVisibleType); float transformationAmount = calculateTransformationAmount(); shownView.transformFrom(hiddenView, transformationAmount); hiddenView.transformTo(shownView, transformationAmount); } else { updateViewVisibilities(visibleType); } } private float calculateTransformationAmount() { int startHeight = getViewForVisibleType(mTransformationStartVisibleType).getHeight(); int endHeight = getViewForVisibleType(mVisibleType).getHeight(); int progress = Math.abs(mContentHeight - startHeight); int totalDistance = Math.abs(endHeight - startHeight); float amount = (float) progress / (float) totalDistance; return Math.min(1.0f, amount); } public int getContentHeight() { return mContentHeight; } Loading Loading @@ -397,6 +435,10 @@ public class NotificationContentView extends FrameLayout { if (mContractedChild == null) { return; } if (mUserExpanding) { updateContentTransformation(); return; } int visibleType = calculateVisibleType(); if (visibleType != mVisibleType || force) { if (animate && ((visibleType == VISIBLE_TYPE_EXPANDED && mExpandedChild != null) Loading Loading @@ -492,9 +534,21 @@ public class NotificationContentView extends FrameLayout { * @return one of the static enum types in this view, calculated form the current state */ private int calculateVisibleType() { boolean noExpandedChild = mExpandedChild == null; if (mUserExpanding) { int expandedVisualType = getVisualTypeForHeight( mContainingNotification.getMaxExpandHeight()); int collapsedVisualType = getVisualTypeForHeight( mContainingNotification.getMinExpandHeight()); return mTransformationStartVisibleType == collapsedVisualType ? expandedVisualType : collapsedVisualType; } int viewHeight = Math.min(mContentHeight, mContainingNotification.getIntrinsicHeight()); return getVisualTypeForHeight(viewHeight); } private int getVisualTypeForHeight(float viewHeight) { boolean noExpandedChild = mExpandedChild == null; if (!noExpandedChild && viewHeight == mExpandedChild.getHeight()) { return VISIBLE_TYPE_EXPANDED; } Loading Loading @@ -723,4 +777,15 @@ public class NotificationContentView extends FrameLayout { updateSingleLineView(); } } public void setUserExpanding(boolean userExpanding) { mUserExpanding = userExpanding; if (userExpanding) { mTransformationStartVisibleType = mVisibleType; } else { mTransformationStartVisibleType = UNDEFINED; mVisibleType = calculateVisibleType(); updateViewVisibilities(mVisibleType); } } }
packages/SystemUI/src/com/android/systemui/statusbar/TransformableView.java +20 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ public interface TransformableView { /** * Get the current state of a view in a transform animation * * @param fadingView which view we are interested in * @return the current transform state of this viewtype */ Loading @@ -37,18 +38,37 @@ public interface TransformableView { /** * Transform to the given view * * @param notification the view to transform to */ void transformTo(TransformableView notification, Runnable endRunnable); /** * Transform to the given view by a specified amount. * * @param notification the view to transform to * @param transformationAmount how much transformation should be done */ void transformTo(TransformableView notification, float transformationAmount); /** * Transform to this view from the given view * * @param notification the view to transform from */ void transformFrom(TransformableView notification); /** * Transform to this view from the given view by a specified amount. * * @param notification the view to transform from * @param transformationAmount how much transformation should be done */ void transformFrom(TransformableView notification, float transformationAmount); /** * Set this view to be fully visible or gone * * @param visible */ void setVisible(boolean visible); Loading