Merge "Added fake shadows in order to have the shadow nicely fade in" into nyc-dev
am: 9d120733a6
* commit '9d120733a66801a721108eb740596ab3ff08c940':
Added fake shadows in order to have the shadow nicely fade in
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
android:focusable="true"
|
||||
android:clickable="true"
|
||||
>
|
||||
|
||||
<com.android.systemui.statusbar.NotificationBackgroundView android:id="@+id/backgroundNormal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -65,4 +66,9 @@
|
||||
/>
|
||||
</com.android.keyguard.AlphaOptimizedLinearLayout>
|
||||
|
||||
<com.android.systemui.statusbar.notification.FakeShadowView
|
||||
android:id="@+id/fake_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</com.android.systemui.statusbar.NotificationOverflowContainer>
|
||||
|
||||
@@ -76,4 +76,9 @@
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
|
||||
<com.android.systemui.statusbar.notification.FakeShadowView
|
||||
android:id="@+id/fake_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</com.android.systemui.statusbar.ExpandableNotificationRow>
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.view.animation.PathInterpolator;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.classifier.FalsingManager;
|
||||
import com.android.systemui.statusbar.notification.FakeShadowView;
|
||||
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
|
||||
|
||||
/**
|
||||
@@ -155,6 +156,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
}
|
||||
};
|
||||
private float mShadowAlpha = 1.0f;
|
||||
private FakeShadowView mFakeShadow;
|
||||
|
||||
public ActivatableNotificationView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
@@ -180,6 +182,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mBackgroundNormal = (NotificationBackgroundView) findViewById(R.id.backgroundNormal);
|
||||
mFakeShadow = (FakeShadowView) findViewById(R.id.fake_shadow);
|
||||
mBackgroundDimmed = (NotificationBackgroundView) findViewById(R.id.backgroundDimmed);
|
||||
mBackgroundNormal.setCustomBackground(R.drawable.notification_material_bg);
|
||||
mBackgroundDimmed.setCustomBackground(R.drawable.notification_material_bg_dim);
|
||||
@@ -852,6 +855,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFakeShadowIntensity(float shadowIntensity, float outlineAlpha, int shadowYEnd,
|
||||
int outlineTranslation) {
|
||||
mFakeShadow.setFakeShadowTranslationZ(shadowIntensity * (getTranslationZ()
|
||||
+ FakeShadowView.SHADOW_SIBLING_TRESHOLD), outlineAlpha, shadowYEnd,
|
||||
outlineTranslation);
|
||||
}
|
||||
|
||||
public interface OnActivatedListener {
|
||||
void onActivated(ActivatableNotificationView view);
|
||||
void onActivationReset(ActivatableNotificationView view);
|
||||
|
||||
@@ -70,6 +70,11 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getOutlineAlpha() {
|
||||
return mOutlineAlpha;
|
||||
}
|
||||
|
||||
protected void setOutlineRect(RectF rect) {
|
||||
if (rect != null) {
|
||||
setOutlineRect(rect.left, rect.top, rect.right, rect.bottom);
|
||||
@@ -80,6 +85,11 @@ public abstract class ExpandableOutlineView extends ExpandableView {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOutlineTranslation() {
|
||||
return mCustomOutline ? mOutlineRect.left : 0;
|
||||
}
|
||||
|
||||
protected void setOutlineRect(float left, float top, float right, float bottom) {
|
||||
setOutlineRect(true, left, top, right, bottom);
|
||||
}
|
||||
|
||||
@@ -399,6 +399,18 @@ public abstract class ExpandableView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setFakeShadowIntensity(float shadowIntensity, float outlineAlpha, int shadowYEnd,
|
||||
int outlineTranslation) {
|
||||
}
|
||||
|
||||
public float getOutlineAlpha() {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
public int getOutlineTranslation() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* A listener notifying when {@link #getActualHeight} changes.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.notification;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.graphics.Outline;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.statusbar.AlphaOptimizedFrameLayout;
|
||||
|
||||
/**
|
||||
* A view used to cast a shadow of a certain size on another view
|
||||
*/
|
||||
public class FakeShadowView extends AlphaOptimizedFrameLayout {
|
||||
public static final float SHADOW_SIBLING_TRESHOLD = 0.1f;
|
||||
|
||||
private View mFakeShadow;
|
||||
private float mOutlineAlpha;
|
||||
|
||||
public FakeShadowView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public FakeShadowView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public FakeShadowView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public FakeShadowView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
mFakeShadow = new View(context);
|
||||
mFakeShadow.setVisibility(INVISIBLE);
|
||||
mFakeShadow.setLayoutParams(new LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
(int) (48 * getResources().getDisplayMetrics().density)));
|
||||
mFakeShadow.setOutlineProvider(new ViewOutlineProvider() {
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
outline.setRect(0, 0, getWidth(), mFakeShadow.getHeight());
|
||||
outline.setAlpha(mOutlineAlpha);
|
||||
}
|
||||
});
|
||||
addView(mFakeShadow);
|
||||
}
|
||||
|
||||
public void setFakeShadowTranslationZ(float fakeShadowTranslationZ, float outlineAlpha,
|
||||
int shadowYEnd, int outlineTranslation) {
|
||||
if (fakeShadowTranslationZ == 0.0f) {
|
||||
mFakeShadow.setVisibility(INVISIBLE);
|
||||
} else {
|
||||
mFakeShadow.setVisibility(VISIBLE);
|
||||
mFakeShadow.setTranslationZ(fakeShadowTranslationZ);
|
||||
mFakeShadow.setTranslationX(outlineTranslation);
|
||||
mFakeShadow.setTranslationY(shadowYEnd - mFakeShadow.getHeight());
|
||||
if (outlineAlpha != mOutlineAlpha) {
|
||||
mOutlineAlpha = outlineAlpha;
|
||||
mFakeShadow.invalidateOutline();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,6 +63,7 @@ import com.android.systemui.statusbar.NotificationSettingsIconRow;
|
||||
import com.android.systemui.statusbar.NotificationSettingsIconRow.SettingsIconRowListener;
|
||||
import com.android.systemui.statusbar.StackScrollerDecorView;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.notification.FakeShadowView;
|
||||
import com.android.systemui.statusbar.phone.NotificationGroupManager;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
import com.android.systemui.statusbar.phone.ScrimController;
|
||||
@@ -70,6 +71,8 @@ import com.android.systemui.statusbar.policy.HeadsUpManager;
|
||||
import com.android.systemui.statusbar.policy.ScrollAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
@@ -93,7 +96,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
private static final int INVALID_POINTER = -1;
|
||||
|
||||
private ExpandHelper mExpandHelper;
|
||||
private SwipeHelper mSwipeHelper;
|
||||
private NotificationSwipeHelper mSwipeHelper;
|
||||
private boolean mSwipingInProgress;
|
||||
private int mCurrentStackHeight = Integer.MAX_VALUE;
|
||||
private final Paint mBackgroundPaint = new Paint();
|
||||
@@ -277,6 +280,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
private int mBgColor;
|
||||
private float mDimAmount;
|
||||
private ValueAnimator mDimAnimator;
|
||||
private ArrayList<ExpandableView> mTmpSortedChildren = new ArrayList<>();
|
||||
private Animator.AnimatorListener mDimEndListener = new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
@@ -292,6 +296,31 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
};
|
||||
private ViewGroup mQsContainer;
|
||||
private boolean mContinuousShadowUpdate;
|
||||
private ViewTreeObserver.OnPreDrawListener mShadowUpdater
|
||||
= new ViewTreeObserver.OnPreDrawListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
updateViewShadows();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
private Comparator<ExpandableView> mViewPositionComparator = new Comparator<ExpandableView>() {
|
||||
@Override
|
||||
public int compare(ExpandableView view, ExpandableView otherView) {
|
||||
float endY = view.getTranslationY() + view.getActualHeight();
|
||||
float otherEndY = otherView.getTranslationY() + otherView.getActualHeight();
|
||||
if (endY < otherEndY) {
|
||||
return -1;
|
||||
} else if (endY > otherEndY) {
|
||||
return 1;
|
||||
} else {
|
||||
// The two notifications end at the same location
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public NotificationStackScrollLayout(Context context) {
|
||||
this(context, null);
|
||||
@@ -667,6 +696,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
mSwipedOutViews.add(v);
|
||||
mAmbientState.onDragFinished(v);
|
||||
updateContinuousShadowDrawing();
|
||||
if (v instanceof ExpandableNotificationRow) {
|
||||
ExpandableNotificationRow row = (ExpandableNotificationRow) v;
|
||||
if (row.isHeadsUp()) {
|
||||
@@ -689,6 +719,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
@Override
|
||||
public void onChildSnappedBack(View animView, float targetLeft) {
|
||||
mAmbientState.onDragFinished(animView);
|
||||
updateContinuousShadowDrawing();
|
||||
if (!mDragAnimPendingChildren.contains(animView)) {
|
||||
if (mAnimationsEnabled) {
|
||||
mSnappedBackChildren.add(animView);
|
||||
@@ -721,6 +752,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
mFalsingManager.onNotificatonStartDismissing();
|
||||
setSwipingInProgress(true);
|
||||
mAmbientState.onBeginDrag(v);
|
||||
updateContinuousShadowDrawing();
|
||||
if (mAnimationsEnabled && (mIsExpanded || !isPinnedHeadsUp(v))) {
|
||||
mDragAnimPendingChildren.add(v);
|
||||
mNeedsAnimation = true;
|
||||
@@ -2242,6 +2274,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
setAnimationRunning(true);
|
||||
mAnimationEvents.clear();
|
||||
updateBackground();
|
||||
updateViewShadows();
|
||||
} else {
|
||||
applyCurrentState();
|
||||
}
|
||||
@@ -2824,6 +2857,43 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
runAnimationFinishedRunnables();
|
||||
updateBackground();
|
||||
updateViewShadows();
|
||||
}
|
||||
|
||||
private void updateViewShadows() {
|
||||
// we need to work around an issue where the shadow would not cast between siblings when
|
||||
// their z difference is between 0 and 0.1
|
||||
|
||||
// Lefts first sort by Z difference
|
||||
for (int i = 0; i < getChildCount(); i++) {
|
||||
ExpandableView child = (ExpandableView) getChildAt(i);
|
||||
if (child.getVisibility() != GONE) {
|
||||
mTmpSortedChildren.add(child);
|
||||
}
|
||||
}
|
||||
Collections.sort(mTmpSortedChildren, mViewPositionComparator);
|
||||
|
||||
// Now lets update the shadow for the views
|
||||
ExpandableView previous = null;
|
||||
for (int i = 0; i < mTmpSortedChildren.size(); i++) {
|
||||
ExpandableView expandableView = mTmpSortedChildren.get(i);
|
||||
float translationZ = expandableView.getTranslationZ();
|
||||
float otherZ = previous == null ? translationZ : previous.getTranslationZ();
|
||||
float diff = otherZ - translationZ;
|
||||
if (diff <= 0.0f || diff >= FakeShadowView.SHADOW_SIBLING_TRESHOLD) {
|
||||
// There is no fake shadow to be drawn
|
||||
expandableView.setFakeShadowIntensity(0.0f, 0.0f, 0, 0);
|
||||
} else {
|
||||
float yLocation = previous.getTranslationY() + previous.getActualHeight() -
|
||||
expandableView.getTranslationY();
|
||||
expandableView.setFakeShadowIntensity(diff / FakeShadowView.SHADOW_SIBLING_TRESHOLD,
|
||||
previous.getOutlineAlpha(), (int) yLocation,
|
||||
previous.getOutlineTranslation());
|
||||
}
|
||||
previous = expandableView;
|
||||
}
|
||||
|
||||
mTmpSortedChildren.clear();
|
||||
}
|
||||
|
||||
public void goToFullShade(long delay) {
|
||||
@@ -3262,6 +3332,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
getViewTreeObserver().removeOnPreDrawListener(mBackgroundUpdater);
|
||||
}
|
||||
mAnimationRunning = animationRunning;
|
||||
updateContinuousShadowDrawing();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3549,6 +3620,18 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
}
|
||||
|
||||
private void updateContinuousShadowDrawing() {
|
||||
boolean continuousShadowUpdate = mAnimationRunning
|
||||
|| !mAmbientState.getDraggedViews().isEmpty();
|
||||
if (continuousShadowUpdate != mContinuousShadowUpdate) {
|
||||
if (continuousShadowUpdate) {
|
||||
getViewTreeObserver().addOnPreDrawListener(mShadowUpdater);
|
||||
} else {
|
||||
getViewTreeObserver().removeOnPreDrawListener(mShadowUpdater);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class AnimationEvent {
|
||||
|
||||
static AnimationFilter[] FILTERS = new AnimationFilter[] {
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.view.ViewGroup;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.ExpandableView;
|
||||
import com.android.systemui.statusbar.notification.FakeShadowView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -605,20 +606,40 @@ public class StackScrollAlgorithm {
|
||||
private void updateZValuesForState(StackScrollState resultState,
|
||||
StackScrollAlgorithmState algorithmState, AmbientState ambientState) {
|
||||
int childCount = algorithmState.visibleChildren.size();
|
||||
int childrenOnTop = 0;
|
||||
float childrenOnTop = 0.0f;
|
||||
for (int i = childCount - 1; i >= 0; i--) {
|
||||
ExpandableView child = algorithmState.visibleChildren.get(i);
|
||||
StackViewState childViewState = resultState.getViewStateForView(child);
|
||||
if (i > (childCount - 1 - algorithmState.itemsInBottomStack)) {
|
||||
// We are in the bottom stack
|
||||
float numItemsAbove = i - (childCount - 1 - algorithmState.itemsInBottomStack);
|
||||
childViewState.zTranslation = mZBasicHeight
|
||||
- numItemsAbove * mZDistanceBetweenElements;
|
||||
float zSubtraction;
|
||||
if (numItemsAbove <= 1.0f) {
|
||||
float factor = 0.2f;
|
||||
// Lets fade in slower to the threshold to make the shadow fade in look nicer
|
||||
if (numItemsAbove <= factor) {
|
||||
zSubtraction = FakeShadowView.SHADOW_SIBLING_TRESHOLD
|
||||
* numItemsAbove * (1.0f / factor);
|
||||
} else {
|
||||
zSubtraction = FakeShadowView.SHADOW_SIBLING_TRESHOLD
|
||||
+ (numItemsAbove - factor) * (1.0f / (1.0f - factor))
|
||||
* (mZDistanceBetweenElements
|
||||
- FakeShadowView.SHADOW_SIBLING_TRESHOLD);
|
||||
}
|
||||
} else {
|
||||
zSubtraction = numItemsAbove * mZDistanceBetweenElements;
|
||||
}
|
||||
childViewState.zTranslation = mZBasicHeight - zSubtraction;
|
||||
} else if (child.mustStayOnScreen()
|
||||
&& childViewState.yTranslation < ambientState.getTopPadding()
|
||||
+ ambientState.getStackTranslation()) {
|
||||
// TODO; do this more cleanly
|
||||
childrenOnTop++;
|
||||
if (childrenOnTop != 0.0f) {
|
||||
childrenOnTop++;
|
||||
} else {
|
||||
float overlap = ambientState.getTopPadding()
|
||||
+ ambientState.getStackTranslation() - childViewState.yTranslation;
|
||||
childrenOnTop += Math.min(1.0f, overlap / childViewState.height);
|
||||
}
|
||||
childViewState.zTranslation = mZBasicHeight
|
||||
+ childrenOnTop * mZDistanceBetweenElements;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user