Implemented animations for rounding
The corners now animate nicely instead of just jumping. Bug: 69168591 Test: manual, swipe away notifications Change-Id: Ia45774b1fed4d7b0a5cf2ec56ff1560ff685503c
This commit is contained in:
@@ -77,6 +77,14 @@
|
||||
<item type="id" name="action_move_tl_30" />
|
||||
<item type="id" name="action_move_rb_full" />
|
||||
|
||||
<item type="id" name="bottom_roundess_animator_tag"/>
|
||||
<item type="id" name="bottom_roundess_animator_start_tag"/>
|
||||
<item type="id" name="bottom_roundess_animator_end_tag"/>
|
||||
|
||||
<item type="id" name="top_roundess_animator_tag"/>
|
||||
<item type="id" name="top_roundess_animator_start_tag"/>
|
||||
<item type="id" name="top_roundess_animator_end_tag"/>
|
||||
|
||||
<!-- Accessibility actions for the notification menu -->
|
||||
<item type="id" name="action_snooze_undo"/>
|
||||
<item type="id" name="action_snooze_shorter"/>
|
||||
|
||||
@@ -904,7 +904,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
@Override
|
||||
protected void applyRoundness() {
|
||||
super.applyRoundness();
|
||||
applyBackgroundRoundness(getBackgroundRadiusTop(), getBackgroundRadiusBottom());
|
||||
applyBackgroundRoundness(getCurrentBackgroundRadiusTop(),
|
||||
getCurrentBackgroundRadiusBottom());
|
||||
}
|
||||
|
||||
protected void applyBackgroundRoundness(float topRadius, float bottomRadius) {
|
||||
|
||||
@@ -1025,6 +1025,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
mKeepInParent = keepInParent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRemoved() {
|
||||
return mRemoved;
|
||||
}
|
||||
|
||||
@@ -29,12 +29,33 @@ import android.view.ViewOutlineProvider;
|
||||
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||
import com.android.systemui.statusbar.stack.AnimationProperties;
|
||||
import com.android.systemui.statusbar.stack.StackStateAnimator;
|
||||
|
||||
/**
|
||||
* Like {@link ExpandableView}, but setting an outline for the height and clipping.
|
||||
*/
|
||||
public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
|
||||
private static final AnimatableProperty TOP_ROUNDNESS = AnimatableProperty.from(
|
||||
"topRoundness",
|
||||
ExpandableOutlineView::setTopRoundnessInternal,
|
||||
ExpandableOutlineView::getCurrentTopRoundness,
|
||||
R.id.top_roundess_animator_tag,
|
||||
R.id.top_roundess_animator_end_tag,
|
||||
R.id.top_roundess_animator_start_tag);
|
||||
private static final AnimatableProperty BOTTOM_ROUNDNESS = AnimatableProperty.from(
|
||||
"bottomRoundness",
|
||||
ExpandableOutlineView::setBottomRoundnessInternal,
|
||||
ExpandableOutlineView::getCurrentBottomRoundness,
|
||||
R.id.bottom_roundess_animator_tag,
|
||||
R.id.bottom_roundess_animator_end_tag,
|
||||
R.id.bottom_roundess_animator_start_tag);
|
||||
private static final AnimationProperties ROUNDNESS_PROPERTIES =
|
||||
new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
|
||||
|
||||
private final Rect mOutlineRect = new Rect();
|
||||
private boolean mCustomOutline;
|
||||
private float mOutlineAlpha = -1f;
|
||||
@@ -42,8 +63,10 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
private boolean mAlwaysRoundBothCorners;
|
||||
private Path mTmpPath = new Path();
|
||||
private Path mTmpPath2 = new Path();
|
||||
private float mCurrentBottomRoundness;
|
||||
private float mCurrentTopRoundness;
|
||||
private float mBottomRoundness;
|
||||
private float mTopRoundness;
|
||||
private float mBottomRoundNess;
|
||||
|
||||
/**
|
||||
* {@code true} if the children views of the {@link ExpandableOutlineView} are translated when
|
||||
@@ -94,15 +117,15 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
return null;
|
||||
}
|
||||
float topRoundness = mAlwaysRoundBothCorners
|
||||
? mOutlineRadius : mTopRoundness * mOutlineRadius;
|
||||
? mOutlineRadius : mCurrentTopRoundness * mOutlineRadius;
|
||||
float bottomRoundness = mAlwaysRoundBothCorners
|
||||
? mOutlineRadius : mBottomRoundNess * mOutlineRadius;
|
||||
? mOutlineRadius : mCurrentBottomRoundness * mOutlineRadius;
|
||||
if (topRoundness + bottomRoundness > height) {
|
||||
float overShoot = topRoundness + bottomRoundness - height;
|
||||
topRoundness -= overShoot * mTopRoundness
|
||||
/ (mTopRoundness + mBottomRoundNess);
|
||||
bottomRoundness -= overShoot * mBottomRoundNess
|
||||
/ (mTopRoundness + mBottomRoundNess);
|
||||
topRoundness -= overShoot * mCurrentTopRoundness
|
||||
/ (mCurrentTopRoundness + mCurrentBottomRoundness);
|
||||
bottomRoundness -= overShoot * mCurrentBottomRoundness
|
||||
/ (mCurrentTopRoundness + mCurrentBottomRoundness);
|
||||
}
|
||||
getRoundedRectPath(left, top, right, bottom, topRoundness,
|
||||
bottomRoundness, mTmpPath);
|
||||
@@ -158,8 +181,8 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
canvas.save();
|
||||
if (needsContentClipping() && (mAlwaysRoundBothCorners || mTopRoundness > 0
|
||||
|| mBottomRoundNess > 0 || mCustomOutline)) {
|
||||
if (needsContentClipping() && (mAlwaysRoundBothCorners || mCurrentTopRoundness > 0
|
||||
|| mCurrentBottomRoundness > 0 || mCustomOutline)) {
|
||||
Path clipPath = getCustomClipPath();
|
||||
if (clipPath == null) {
|
||||
clipPath = getClipPath();
|
||||
@@ -189,10 +212,11 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
setClipToOutline(mAlwaysRoundBothCorners);
|
||||
}
|
||||
|
||||
public void setTopRoundness(float topRoundness) {
|
||||
public void setTopRoundness(float topRoundness, boolean animate) {
|
||||
if (mTopRoundness != topRoundness) {
|
||||
mTopRoundness = topRoundness;
|
||||
applyRoundness();
|
||||
PropertyAnimator.setProperty(this, TOP_ROUNDNESS, topRoundness,
|
||||
ROUNDNESS_PROPERTIES, animate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,25 +225,41 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
protected float getBackgroundRadiusTop() {
|
||||
return mTopRoundness * mOutlineRadius;
|
||||
protected float getCurrentBackgroundRadiusTop() {
|
||||
return mCurrentTopRoundness * mOutlineRadius;
|
||||
}
|
||||
|
||||
protected float getTopRoundness() {
|
||||
return mTopRoundness;
|
||||
protected float getCurrentTopRoundness() {
|
||||
return mCurrentTopRoundness;
|
||||
}
|
||||
|
||||
protected float getBackgroundRadiusBottom() {
|
||||
return mBottomRoundNess * mOutlineRadius;
|
||||
protected float getCurrentBottomRoundness() {
|
||||
return mCurrentBottomRoundness;
|
||||
}
|
||||
|
||||
public void setBottomRoundNess(float bottomRoundness) {
|
||||
if (mBottomRoundNess != bottomRoundness) {
|
||||
mBottomRoundNess = bottomRoundness;
|
||||
applyRoundness();
|
||||
protected float getCurrentBackgroundRadiusBottom() {
|
||||
return mCurrentBottomRoundness * mOutlineRadius;
|
||||
}
|
||||
|
||||
public void setBottomRoundNess(float bottomRoundness, boolean animate) {
|
||||
if (mBottomRoundness != bottomRoundness) {
|
||||
mBottomRoundness = bottomRoundness;
|
||||
PropertyAnimator.setProperty(this, BOTTOM_ROUNDNESS, bottomRoundness,
|
||||
ROUNDNESS_PROPERTIES, animate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setTopRoundnessInternal(float topRoundness) {
|
||||
mCurrentTopRoundness = topRoundness;
|
||||
applyRoundness();
|
||||
}
|
||||
|
||||
private void setBottomRoundnessInternal(float bottomRoundness) {
|
||||
mCurrentBottomRoundness = bottomRoundness;
|
||||
applyRoundness();
|
||||
}
|
||||
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
initDimens();
|
||||
applyRoundness();
|
||||
|
||||
@@ -202,6 +202,10 @@ public abstract class ExpandableView extends FrameLayout {
|
||||
return mDark;
|
||||
}
|
||||
|
||||
public boolean isRemoved() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #setHideSensitive}. This is a variant which notifies this view in advance about
|
||||
* the upcoming state of hiding sensitive notifications. It gets called at the very beginning
|
||||
|
||||
@@ -111,7 +111,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
||||
mViewInvertHelper = new ViewInvertHelper(mShelfIcons,
|
||||
NotificationPanelView.DOZE_ANIMATION_DURATION);
|
||||
mShelfState = new ShelfState();
|
||||
setBottomRoundNess(1.0f);
|
||||
setBottomRoundNess(1.0f, false /* animate */);
|
||||
initDimens();
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
||||
if (iconState.clampedAppearAmount == 1.0f) {
|
||||
// only if the first icon is fully in the shelf we want to clip to it!
|
||||
mCustomClipTop = (int) (row.getTranslationY() - getTranslationY());
|
||||
mFirstElementTopRoundness = row.getBackgroundRadiusTop();
|
||||
mFirstElementTopRoundness = row.getCurrentBackgroundRadiusTop();
|
||||
contentNeedsClipping = true;
|
||||
}
|
||||
}
|
||||
@@ -356,7 +356,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
|
||||
return null;
|
||||
}
|
||||
return getRoundedRectPath(0, mCustomClipTop, getWidth(), getHeight(),
|
||||
mFirstElementTopRoundness, getBackgroundRadiusBottom());
|
||||
mFirstElementTopRoundness, getCurrentBackgroundRadiusBottom());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2831,21 +2831,34 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
mAnimateNextBackgroundTop = false;
|
||||
mAnimateNextBackgroundBottom = false;
|
||||
}
|
||||
if (firstChanged && mFirstVisibleBackgroundChild != null) {
|
||||
mFirstVisibleBackgroundChild.setTopRoundness(0.0f);
|
||||
if (firstChanged && mFirstVisibleBackgroundChild != null
|
||||
&& !mFirstVisibleBackgroundChild.isRemoved()) {
|
||||
mFirstVisibleBackgroundChild.setTopRoundness(0.0f,
|
||||
mFirstVisibleBackgroundChild.isShown());
|
||||
}
|
||||
if (lastChanged && mLastVisibleBackgroundChild != null) {
|
||||
mLastVisibleBackgroundChild.setBottomRoundNess(0.0f);
|
||||
if (lastChanged && mLastVisibleBackgroundChild != null
|
||||
&& !mLastVisibleBackgroundChild.isRemoved()) {
|
||||
mLastVisibleBackgroundChild.setBottomRoundNess(0.0f,
|
||||
mLastVisibleBackgroundChild.isShown());
|
||||
}
|
||||
mFirstVisibleBackgroundChild = firstChild;
|
||||
mLastVisibleBackgroundChild = lastChild;
|
||||
applyRoundedNess();
|
||||
mAmbientState.setLastVisibleBackgroundChild(lastChild);
|
||||
}
|
||||
|
||||
private void applyRoundedNess() {
|
||||
if (mFirstVisibleBackgroundChild != null) {
|
||||
mFirstVisibleBackgroundChild.setTopRoundness(1.0f);
|
||||
mFirstVisibleBackgroundChild.setTopRoundness(
|
||||
mStatusBarState == StatusBarState.KEYGUARD ? 1.0f : 0.0f,
|
||||
mFirstVisibleBackgroundChild.isShown()
|
||||
&& !mChildrenToAddAnimated.contains(mFirstVisibleBackgroundChild));
|
||||
}
|
||||
if (mLastVisibleBackgroundChild != null) {
|
||||
mLastVisibleBackgroundChild.setBottomRoundNess(1.0f);
|
||||
mLastVisibleBackgroundChild.setBottomRoundNess(1.0f,
|
||||
mLastVisibleBackgroundChild.isShown()
|
||||
&& !mChildrenToAddAnimated.contains(mLastVisibleBackgroundChild));
|
||||
}
|
||||
mAmbientState.setLastVisibleBackgroundChild(lastChild);
|
||||
}
|
||||
|
||||
private void onViewAddedInternal(View child) {
|
||||
@@ -4300,6 +4313,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
public void setStatusBarState(int statusBarState) {
|
||||
mStatusBarState = statusBarState;
|
||||
mAmbientState.setStatusBarState(statusBarState);
|
||||
applyRoundedNess();
|
||||
}
|
||||
|
||||
public void setExpandingVelocity(float expandingVelocity) {
|
||||
|
||||
Reference in New Issue
Block a user