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:
Selim Cinek
2017-11-10 17:53:47 -08:00
parent 0228a255d6
commit d9b7dd4a5d
7 changed files with 100 additions and 32 deletions

View File

@@ -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"/>

View File

@@ -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) {

View File

@@ -1025,6 +1025,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
mKeepInParent = keepInParent;
}
@Override
public boolean isRemoved() {
return mRemoved;
}

View File

@@ -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();

View File

@@ -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

View File

@@ -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

View File

@@ -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) {