Adapted the animation to the full shade
The background and the shelf now animate properly on the lockscreen when going to the full shade. Test: Go to lockscreen from keyguard Bug: 32437839 Change-Id: Idd7e8325cc91464ed9c943c5ae311576d8aaaebc
This commit is contained in:
@@ -47,6 +47,8 @@ public abstract class ExpandableView extends FrameLayout {
|
||||
private boolean mClipToActualHeight = true;
|
||||
private boolean mChangingPosition = false;
|
||||
private ViewGroup mTransientContainer;
|
||||
private boolean mInShelf;
|
||||
private boolean mTransformingInShelf;
|
||||
|
||||
public ExpandableView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -475,6 +477,29 @@ public abstract class ExpandableView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inShelf whether the view is currently fully in the notification shelf.
|
||||
*/
|
||||
public void setInShelf(boolean inShelf) {
|
||||
mInShelf = inShelf;
|
||||
}
|
||||
|
||||
public boolean isInShelf() {
|
||||
return mInShelf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param transformingInShelf whether the view is currently transforming into the shelf in an
|
||||
* animated way
|
||||
*/
|
||||
public void setTransformingInShelf(boolean transformingInShelf) {
|
||||
mTransformingInShelf = transformingInShelf;
|
||||
}
|
||||
|
||||
public boolean isTransformingIntoShelf() {
|
||||
return mTransformingInShelf;
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener notifying when {@link #getActualHeight} changes.
|
||||
*/
|
||||
|
||||
@@ -60,6 +60,8 @@ public class NotificationShelf extends ActivatableNotificationView {
|
||||
private NotificationStackScrollLayout mHostLayout;
|
||||
private int mMaxLayoutHeight;
|
||||
private int mPaddingBetweenElements;
|
||||
private int mNotGoneIndex;
|
||||
private boolean mHasItemsInStableShelf;
|
||||
|
||||
public NotificationShelf(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -154,9 +156,14 @@ public class NotificationShelf extends ActivatableNotificationView {
|
||||
mShelfState.shadowAlpha = 1.0f;
|
||||
mShelfState.isBottomClipped = false;
|
||||
mShelfState.hideSensitive = false;
|
||||
if (mNotGoneIndex != -1) {
|
||||
mShelfState.notGoneIndex = Math.min(mShelfState.notGoneIndex, mNotGoneIndex);
|
||||
}
|
||||
mShelfState.hasItemsInStableShelf = lastViewState.inShelf;
|
||||
} else {
|
||||
mShelfState.hidden = true;
|
||||
mShelfState.location = ExpandableViewState.LOCATION_GONE;
|
||||
mShelfState.hasItemsInStableShelf = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +176,7 @@ public class NotificationShelf extends ActivatableNotificationView {
|
||||
mNotificationIconContainer.resetViewStates();
|
||||
float numIconsInShelf = 0.0f;
|
||||
int shelfIndex = mAmbientState.getShelfIndex();
|
||||
mNotGoneIndex = -1;
|
||||
// find the first view that doesn't overlap with the shelf
|
||||
for (int i = shelfIndex - 1; i >= 0; i--) {
|
||||
ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
|
||||
@@ -198,6 +206,9 @@ public class NotificationShelf extends ActivatableNotificationView {
|
||||
updateNotificationClipHeight(row, notificationClipEnd);
|
||||
updateIconAppearance(shelfStart, row, iconState, icon);
|
||||
numIconsInShelf += iconState.iconAppearAmount;
|
||||
if (row.getTranslationY() >= getTranslationY()) {
|
||||
mNotGoneIndex = i;
|
||||
}
|
||||
}
|
||||
for (int i = mHostLayout.getChildCount() - 1; i >= shelfIndex; i--) {
|
||||
// We need to reset the clipping in case a notification switches from high to low
|
||||
@@ -301,6 +312,13 @@ public class NotificationShelf extends ActivatableNotificationView {
|
||||
iconState.hidden = transitionAmount == 0.0f;
|
||||
row.setIconTransformationAmount(transitionAmount);
|
||||
icon.setVisibility(transitionAmount == 0.0f ? INVISIBLE : VISIBLE);
|
||||
if (row.isInShelf() && !row.isTransformingIntoShelf()) {
|
||||
iconState.iconAppearAmount = 1.0f;
|
||||
iconState.alpha = 1.0f;
|
||||
iconState.scaleX = shelfIconSize / icon.getHeight();
|
||||
iconState.scaleY = iconState.scaleX;
|
||||
iconState.hidden = false;
|
||||
}
|
||||
}
|
||||
|
||||
private float getFullyClosedTranslation() {
|
||||
@@ -335,6 +353,10 @@ public class NotificationShelf extends ActivatableNotificationView {
|
||||
updateOutline();
|
||||
}
|
||||
|
||||
public boolean hidesBackground() {
|
||||
return mHideBackground;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needsOutline() {
|
||||
return !mHideBackground && super.needsOutline();
|
||||
@@ -353,14 +375,35 @@ public class NotificationShelf extends ActivatableNotificationView {
|
||||
mMaxLayoutHeight = maxLayoutHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the index of the notification at which the shelf visually resides
|
||||
*/
|
||||
public int getNotGoneIndex() {
|
||||
return mNotGoneIndex;
|
||||
}
|
||||
|
||||
private void setHasItemsInStableShelf(boolean hasItemsInStableShelf) {
|
||||
mHasItemsInStableShelf = hasItemsInStableShelf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether the shelf has any icons in it when a potential animation has finished, i.e
|
||||
* if the current state would be applied right now
|
||||
*/
|
||||
public boolean hasItemsInStableShelf() {
|
||||
return mHasItemsInStableShelf;
|
||||
}
|
||||
|
||||
private class ShelfState extends ExpandableViewState {
|
||||
private float iconContainerTranslation;
|
||||
private boolean hasItemsInStableShelf;
|
||||
|
||||
@Override
|
||||
public void applyToView(View view) {
|
||||
super.applyToView(view);
|
||||
updateAppearance();
|
||||
setIconContainerTranslation(iconContainerTranslation);
|
||||
setHasItemsInStableShelf(hasItemsInStableShelf);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -368,6 +411,7 @@ public class NotificationShelf extends ActivatableNotificationView {
|
||||
super.animateTo(child, properties);
|
||||
updateAppearance();
|
||||
setIconContainerTranslation(iconContainerTranslation);
|
||||
setHasItemsInStableShelf(hasItemsInStableShelf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@ public class ExpandableViewState extends ViewState {
|
||||
public boolean hideSensitive;
|
||||
public boolean belowShelf;
|
||||
public float shadowAlpha;
|
||||
public boolean inShelf;
|
||||
|
||||
/**
|
||||
* How much the child overlaps with the previous child on top. This is used to
|
||||
@@ -171,6 +172,9 @@ public class ExpandableViewState extends ViewState {
|
||||
if (oldClipTopAmount != this.clipTopAmount) {
|
||||
expandableView.setClipTopAmount(this.clipTopAmount);
|
||||
}
|
||||
|
||||
expandableView.setTransformingInShelf(false);
|
||||
expandableView.setInShelf(inShelf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +224,11 @@ public class ExpandableViewState extends ViewState {
|
||||
if (properties.wasAdded(child)) {
|
||||
expandableView.performAddAnimation(properties.delay, properties.duration);
|
||||
}
|
||||
|
||||
if (!expandableView.isInShelf() && this.inShelf) {
|
||||
expandableView.setTransformingInShelf(true);
|
||||
}
|
||||
expandableView.setInShelf(this.inShelf);
|
||||
}
|
||||
|
||||
private void startHeightAnimation(final ExpandableView child, AnimationProperties properties) {
|
||||
|
||||
@@ -2127,10 +2127,17 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
top = (int) firstView.getTranslationY();
|
||||
}
|
||||
}
|
||||
ActivatableNotificationView lastView = mLastVisibleBackgroundChild;
|
||||
ActivatableNotificationView lastView = mShelf.hasItemsInStableShelf()
|
||||
? mShelf
|
||||
: mLastVisibleBackgroundChild;
|
||||
int bottom = 0;
|
||||
if (lastView != null) {
|
||||
int finalTranslationY = (int) ViewState.getFinalTranslationY(lastView);
|
||||
int finalTranslationY;
|
||||
if (lastView == mShelf) {
|
||||
finalTranslationY = (int) mShelf.getTranslationY();
|
||||
} else {
|
||||
finalTranslationY = (int) ViewState.getFinalTranslationY(lastView);
|
||||
}
|
||||
int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
|
||||
int finalBottom = finalTranslationY + finalHeight;
|
||||
finalBottom = Math.min(finalBottom, getHeight());
|
||||
@@ -3979,6 +3986,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
addView(mShelf, index);
|
||||
mAmbientState.setShelf(shelf);
|
||||
mStateAnimator.setShelf(shelf);
|
||||
shelf.bind(mAmbientState, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -501,6 +501,7 @@ public class StackScrollAlgorithm {
|
||||
childViewState.yTranslation = Math.min(childViewState.yTranslation, shelfStart);
|
||||
if (childViewState.yTranslation >= shelfStart) {
|
||||
childViewState.hidden = true;
|
||||
childViewState.inShelf = true;
|
||||
}
|
||||
if (!ambientState.isShadeExpanded()) {
|
||||
childViewState.height = (int) (mStatusBarHeight - childViewState.yTranslation);
|
||||
|
||||
@@ -83,6 +83,7 @@ public class StackScrollState {
|
||||
viewState.hidden = false;
|
||||
viewState.scaleX = view.getScaleX();
|
||||
viewState.scaleY = view.getScaleY();
|
||||
viewState.inShelf = false;
|
||||
}
|
||||
|
||||
public ExpandableViewState getViewStateForView(View requestedView) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.ExpandableView;
|
||||
import com.android.systemui.statusbar.NotificationShelf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -75,6 +76,7 @@ public class StackStateAnimator {
|
||||
private int mHeadsUpAppearHeightBottom;
|
||||
private boolean mShadeExpanded;
|
||||
private ArrayList<View> mChildrenToClearFromOverlay = new ArrayList<>();
|
||||
private NotificationShelf mShelf;
|
||||
|
||||
public StackStateAnimator(NotificationStackScrollLayout hostLayout) {
|
||||
mHostLayout = hostLayout;
|
||||
@@ -287,9 +289,18 @@ public class StackStateAnimator {
|
||||
}
|
||||
|
||||
private long calculateDelayGoToFullShade(ExpandableViewState viewState) {
|
||||
int shelfIndex = mShelf.getNotGoneIndex();
|
||||
float index = viewState.notGoneIndex;
|
||||
long result = 0;
|
||||
if (index > shelfIndex) {
|
||||
float diff = index - shelfIndex;
|
||||
diff = (float) Math.pow(diff, 0.7f);
|
||||
result += (long) (diff * ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE * 0.25);
|
||||
index = shelfIndex;
|
||||
}
|
||||
index = (float) Math.pow(index, 0.7f);
|
||||
return (long) (index * ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE);
|
||||
result += (long) (index * ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -501,4 +512,8 @@ public class StackStateAnimator {
|
||||
public void setShadeExpanded(boolean shadeExpanded) {
|
||||
mShadeExpanded = shadeExpanded;
|
||||
}
|
||||
|
||||
public void setShelf(NotificationShelf shelf) {
|
||||
mShelf = shelf;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user