Merge "Fade notifications when exiting dozing" into lmp-mr1-dev
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
android:layout_height="@dimen/notification_large_icon_height"
|
android:layout_height="@dimen/notification_large_icon_height"
|
||||||
/>
|
/>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/notification_main_column"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_gravity="top"
|
android:layout_gravity="top"
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
android:layout_height="@dimen/notification_large_icon_height"
|
android:layout_height="@dimen/notification_large_icon_height"
|
||||||
/>
|
/>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/notification_main_column"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="top"
|
android:layout_gravity="top"
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
android:layout_height="@dimen/notification_large_icon_height"
|
android:layout_height="@dimen/notification_large_icon_height"
|
||||||
/>
|
/>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/notification_main_column"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="top"
|
android:layout_gravity="top"
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
android:layout_height="@dimen/notification_large_icon_height"
|
android:layout_height="@dimen/notification_large_icon_height"
|
||||||
/>
|
/>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/notification_main_column"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="top"
|
android:layout_gravity="top"
|
||||||
|
|||||||
@@ -202,6 +202,7 @@
|
|||||||
<java-symbol type="id" name="status_bar_latest_event_content" />
|
<java-symbol type="id" name="status_bar_latest_event_content" />
|
||||||
<java-symbol type="id" name="action_divider" />
|
<java-symbol type="id" name="action_divider" />
|
||||||
<java-symbol type="id" name="overflow_divider" />
|
<java-symbol type="id" name="overflow_divider" />
|
||||||
|
<java-symbol type="id" name="notification_main_column" />
|
||||||
<java-symbol type="id" name="sms_short_code_confirm_message" />
|
<java-symbol type="id" name="sms_short_code_confirm_message" />
|
||||||
<java-symbol type="id" name="sms_short_code_detail_layout" />
|
<java-symbol type="id" name="sms_short_code_detail_layout" />
|
||||||
<java-symbol type="id" name="sms_short_code_detail_message" />
|
<java-symbol type="id" name="sms_short_code_detail_message" />
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
101
packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
Normal file
101
packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.graphics.ColorMatrix;
|
||||||
|
import android.graphics.ColorMatrixColorFilter;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
|
import com.android.systemui.statusbar.phone.NotificationPanelView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to invert the colors of views and fade between the states.
|
||||||
|
*/
|
||||||
|
public class ViewInvertHelper {
|
||||||
|
|
||||||
|
private final Paint mDarkPaint = new Paint();
|
||||||
|
private final Interpolator mLinearOutSlowInInterpolator;
|
||||||
|
private final View mTarget;
|
||||||
|
private final ColorMatrix mMatrix = new ColorMatrix();
|
||||||
|
private final ColorMatrix mGrayscaleMatrix = new ColorMatrix();
|
||||||
|
private final long mFadeDuration;
|
||||||
|
|
||||||
|
public ViewInvertHelper(View target, long fadeDuration) {
|
||||||
|
mTarget = target;
|
||||||
|
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(mTarget.getContext(),
|
||||||
|
android.R.interpolator.linear_out_slow_in);
|
||||||
|
mFadeDuration = fadeDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fade(final boolean invert, long delay) {
|
||||||
|
float startIntensity = invert ? 0f : 1f;
|
||||||
|
float endIntensity = invert ? 1f : 0f;
|
||||||
|
ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
|
||||||
|
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
updateInvertPaint((Float) animation.getAnimatedValue());
|
||||||
|
mTarget.setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
animator.addListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
if (!invert) {
|
||||||
|
mTarget.setLayerType(View.LAYER_TYPE_NONE, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
animator.setDuration(mFadeDuration);
|
||||||
|
animator.setInterpolator(mLinearOutSlowInInterpolator);
|
||||||
|
animator.setStartDelay(delay);
|
||||||
|
animator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(boolean invert) {
|
||||||
|
if (invert) {
|
||||||
|
updateInvertPaint(1f);
|
||||||
|
mTarget.setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
|
||||||
|
} else {
|
||||||
|
mTarget.setLayerType(View.LAYER_TYPE_NONE, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public View getTarget() {
|
||||||
|
return mTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateInvertPaint(float intensity) {
|
||||||
|
float components = 1 - 2 * intensity;
|
||||||
|
final float[] invert = {
|
||||||
|
components, 0f, 0f, 0f, 255f * intensity,
|
||||||
|
0f, components, 0f, 0f, 255f * intensity,
|
||||||
|
0f, 0f, components, 0f, 255f * intensity,
|
||||||
|
0f, 0f, 0f, 1f, 0f
|
||||||
|
};
|
||||||
|
mMatrix.set(invert);
|
||||||
|
mGrayscaleMatrix.setSaturation(1 - intensity);
|
||||||
|
mMatrix.preConcat(mGrayscaleMatrix);
|
||||||
|
mDarkPaint.setColorFilter(new ColorMatrixColorFilter(mMatrix));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ import android.view.animation.LinearInterpolator;
|
|||||||
import android.view.animation.PathInterpolator;
|
import android.view.animation.PathInterpolator;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.statusbar.phone.NotificationPanelView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
|
* Base class for both {@link ExpandableNotificationRow} and {@link NotificationOverflowContainer}
|
||||||
@@ -53,6 +54,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
private static final long DOUBLETAP_TIMEOUT_MS = 1200;
|
private static final long DOUBLETAP_TIMEOUT_MS = 1200;
|
||||||
private static final int BACKGROUND_ANIMATION_LENGTH_MS = 220;
|
private static final int BACKGROUND_ANIMATION_LENGTH_MS = 220;
|
||||||
private static final int ACTIVATE_ANIMATION_LENGTH = 220;
|
private static final int ACTIVATE_ANIMATION_LENGTH = 220;
|
||||||
|
private static final int DARK_ANIMATION_LENGTH = 170;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The amount of width, which is kept in the end when performing a disappear animation (also
|
* The amount of width, which is kept in the end when performing a disappear animation (also
|
||||||
@@ -84,6 +86,11 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
*/
|
*/
|
||||||
private static final float VERTICAL_ANIMATION_START = 1.0f;
|
private static final float VERTICAL_ANIMATION_START = 1.0f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scale for the background to animate from when exiting dark mode.
|
||||||
|
*/
|
||||||
|
private static final float DARK_EXIT_SCALE_START = 0.93f;
|
||||||
|
|
||||||
private static final Interpolator ACTIVATE_INVERSE_INTERPOLATOR
|
private static final Interpolator ACTIVATE_INVERSE_INTERPOLATOR
|
||||||
= new PathInterpolator(0.6f, 0, 0.5f, 1);
|
= new PathInterpolator(0.6f, 0, 0.5f, 1);
|
||||||
private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
|
private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
|
||||||
@@ -94,7 +101,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
|
|
||||||
private boolean mDimmed;
|
private boolean mDimmed;
|
||||||
private boolean mDark;
|
private boolean mDark;
|
||||||
private final Paint mDarkPaint = createDarkPaint();
|
|
||||||
|
|
||||||
private int mBgTint = 0;
|
private int mBgTint = 0;
|
||||||
private final int mRoundedRectCornerRadius;
|
private final int mRoundedRectCornerRadius;
|
||||||
@@ -332,41 +338,33 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
if (mDimmed != dimmed) {
|
if (mDimmed != dimmed) {
|
||||||
mDimmed = dimmed;
|
mDimmed = dimmed;
|
||||||
if (fade) {
|
if (fade) {
|
||||||
fadeBackground();
|
fadeDimmedBackground();
|
||||||
} else {
|
} else {
|
||||||
updateBackground();
|
updateBackground();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDark(boolean dark, boolean fade) {
|
public void setDark(boolean dark, boolean fade, long delay) {
|
||||||
// TODO implement fade
|
super.setDark(dark, fade, delay);
|
||||||
if (mDark != dark) {
|
if (mDark == dark) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
mDark = dark;
|
mDark = dark;
|
||||||
if (mDark) {
|
if (!dark && fade) {
|
||||||
setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
|
if (mActivated) {
|
||||||
|
mBackgroundDimmed.setVisibility(View.VISIBLE);
|
||||||
|
mBackgroundNormal.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
setLayerType(View.LAYER_TYPE_NONE, null);
|
mBackgroundDimmed.setVisibility(View.VISIBLE);
|
||||||
|
mBackgroundNormal.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
fadeDarkToDimmed(delay);
|
||||||
|
} else {
|
||||||
|
updateBackground();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Paint createDarkPaint() {
|
|
||||||
final Paint p = new Paint();
|
|
||||||
final float[] invert = {
|
|
||||||
-1f, 0f, 0f, 1f, 1f,
|
|
||||||
0f, -1f, 0f, 1f, 1f,
|
|
||||||
0f, 0f, -1f, 1f, 1f,
|
|
||||||
0f, 0f, 0f, 1f, 0f
|
|
||||||
};
|
|
||||||
final ColorMatrix m = new ColorMatrix(invert);
|
|
||||||
final ColorMatrix grayscale = new ColorMatrix();
|
|
||||||
grayscale.setSaturation(0);
|
|
||||||
m.preConcat(grayscale);
|
|
||||||
p.setColorFilter(new ColorMatrixColorFilter(m));
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setShowingLegacyBackground(boolean showing) {
|
public void setShowingLegacyBackground(boolean showing) {
|
||||||
mShowingLegacyBackground = showing;
|
mShowingLegacyBackground = showing;
|
||||||
updateBackgroundTint();
|
updateBackgroundTint();
|
||||||
@@ -402,7 +400,39 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
mBackgroundNormal.setRippleColor(rippleColor);
|
mBackgroundNormal.setRippleColor(rippleColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fadeBackground() {
|
/**
|
||||||
|
* Fades the dimmed background when exiting dark mode.
|
||||||
|
*/
|
||||||
|
private void fadeDarkToDimmed(long delay) {
|
||||||
|
mBackgroundDimmed.setAlpha(0f);
|
||||||
|
mBackgroundDimmed.setPivotX(mBackgroundDimmed.getWidth() / 2f);
|
||||||
|
mBackgroundDimmed.setPivotY(getActualHeight() / 2f);
|
||||||
|
mBackgroundDimmed.setScaleX(DARK_EXIT_SCALE_START);
|
||||||
|
mBackgroundDimmed.setScaleY(DARK_EXIT_SCALE_START);
|
||||||
|
mBackgroundDimmed.animate()
|
||||||
|
.alpha(1f)
|
||||||
|
.scaleX(1f)
|
||||||
|
.scaleY(1f)
|
||||||
|
.setDuration(DARK_ANIMATION_LENGTH)
|
||||||
|
.setStartDelay(delay)
|
||||||
|
.setInterpolator(mLinearOutSlowInInterpolator)
|
||||||
|
.setListener(new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationCancel(Animator animation) {
|
||||||
|
// Jump state if we are cancelled
|
||||||
|
mBackgroundDimmed.setScaleX(1f);
|
||||||
|
mBackgroundDimmed.setScaleY(1f);
|
||||||
|
mBackgroundDimmed.setAlpha(1f);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fades the background when the dimmed state changes.
|
||||||
|
*/
|
||||||
|
private void fadeDimmedBackground() {
|
||||||
|
mBackgroundDimmed.animate().cancel();
|
||||||
mBackgroundNormal.animate().cancel();
|
mBackgroundNormal.animate().cancel();
|
||||||
if (mDimmed) {
|
if (mDimmed) {
|
||||||
mBackgroundDimmed.setVisibility(View.VISIBLE);
|
mBackgroundDimmed.setVisibility(View.VISIBLE);
|
||||||
@@ -443,11 +473,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateBackground() {
|
private void updateBackground() {
|
||||||
if (mDimmed) {
|
cancelFadeAnimations();
|
||||||
|
if (mDark) {
|
||||||
|
mBackgroundDimmed.setVisibility(View.INVISIBLE);
|
||||||
|
mBackgroundNormal.setVisibility(View.INVISIBLE);
|
||||||
|
} else if (mDimmed) {
|
||||||
mBackgroundDimmed.setVisibility(View.VISIBLE);
|
mBackgroundDimmed.setVisibility(View.VISIBLE);
|
||||||
mBackgroundNormal.setVisibility(View.INVISIBLE);
|
mBackgroundNormal.setVisibility(View.INVISIBLE);
|
||||||
} else {
|
} else {
|
||||||
cancelFadeAnimations();
|
|
||||||
mBackgroundDimmed.setVisibility(View.INVISIBLE);
|
mBackgroundDimmed.setVisibility(View.INVISIBLE);
|
||||||
mBackgroundNormal.setVisibility(View.VISIBLE);
|
mBackgroundNormal.setVisibility(View.VISIBLE);
|
||||||
mBackgroundNormal.setAlpha(1f);
|
mBackgroundNormal.setAlpha(1f);
|
||||||
@@ -459,6 +492,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
|
|||||||
if (mBackgroundAnimator != null) {
|
if (mBackgroundAnimator != null) {
|
||||||
mBackgroundAnimator.cancel();
|
mBackgroundAnimator.cancel();
|
||||||
}
|
}
|
||||||
|
mBackgroundDimmed.animate().cancel();
|
||||||
mBackgroundNormal.animate().cancel();
|
mBackgroundNormal.animate().cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -207,11 +207,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDark(boolean dark, boolean fade) {
|
public void setDark(boolean dark, boolean fade, long delay) {
|
||||||
super.setDark(dark, fade);
|
super.setDark(dark, fade, delay);
|
||||||
final NotificationContentView showing = getShowingLayout();
|
final NotificationContentView showing = getShowingLayout();
|
||||||
if (showing != null) {
|
if (showing != null) {
|
||||||
showing.setDark(dark, fade);
|
showing.setDark(dark, fade, delay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public abstract class ExpandableView extends FrameLayout {
|
|||||||
private int mActualHeight;
|
private int mActualHeight;
|
||||||
protected int mClipTopAmount;
|
protected int mClipTopAmount;
|
||||||
private boolean mActualHeightInitialized;
|
private boolean mActualHeightInitialized;
|
||||||
|
private boolean mDark;
|
||||||
private ArrayList<View> mMatchParentViews = new ArrayList<View>();
|
private ArrayList<View> mMatchParentViews = new ArrayList<View>();
|
||||||
|
|
||||||
public ExpandableView(Context context, AttributeSet attrs) {
|
public ExpandableView(Context context, AttributeSet attrs) {
|
||||||
@@ -185,8 +186,14 @@ public abstract class ExpandableView extends FrameLayout {
|
|||||||
*
|
*
|
||||||
* @param dark Whether the notification should be dark.
|
* @param dark Whether the notification should be dark.
|
||||||
* @param fade Whether an animation should be played to change the state.
|
* @param fade Whether an animation should be played to change the state.
|
||||||
|
* @param delay If fading, the delay of the animation.
|
||||||
*/
|
*/
|
||||||
public void setDark(boolean dark, boolean fade) {
|
public void setDark(boolean dark, boolean fade, long delay) {
|
||||||
|
mDark = dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDark() {
|
||||||
|
return mDark;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ import com.android.systemui.R;
|
|||||||
public class NotificationContentView extends FrameLayout {
|
public class NotificationContentView extends FrameLayout {
|
||||||
|
|
||||||
private static final long ANIMATION_DURATION_LENGTH = 170;
|
private static final long ANIMATION_DURATION_LENGTH = 170;
|
||||||
private static final Paint INVERT_PAINT = createInvertPaint();
|
|
||||||
private static final ColorFilter NO_COLOR_FILTER = new ColorFilter();
|
|
||||||
|
|
||||||
private final Rect mClipBounds = new Rect();
|
private final Rect mClipBounds = new Rect();
|
||||||
|
|
||||||
private View mContractedChild;
|
private View mContractedChild;
|
||||||
private View mExpandedChild;
|
private View mExpandedChild;
|
||||||
|
|
||||||
|
private NotificationViewWrapper mContractedWrapper;
|
||||||
|
|
||||||
private int mSmallHeight;
|
private int mSmallHeight;
|
||||||
private int mClipTopAmount;
|
private int mClipTopAmount;
|
||||||
private int mActualHeight;
|
private int mActualHeight;
|
||||||
@@ -122,6 +122,7 @@ public class NotificationContentView extends FrameLayout {
|
|||||||
sanitizeContractedLayoutParams(child);
|
sanitizeContractedLayoutParams(child);
|
||||||
addView(child);
|
addView(child);
|
||||||
mContractedChild = child;
|
mContractedChild = child;
|
||||||
|
mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child);
|
||||||
selectLayout(false /* animate */, true /* force */);
|
selectLayout(false /* animate */, true /* force */);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,38 +250,10 @@ public class NotificationContentView extends FrameLayout {
|
|||||||
return mExpandedChild != null;
|
return mExpandedChild != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDark(boolean dark, boolean fade) {
|
public void setDark(boolean dark, boolean fade, long delay) {
|
||||||
if (mDark == dark || mContractedChild == null) return;
|
if (mDark == dark || mContractedChild == null) return;
|
||||||
mDark = dark;
|
mDark = dark;
|
||||||
setImageViewDark(dark, fade, com.android.internal.R.id.right_icon);
|
mContractedWrapper.setDark(dark, fade, delay);
|
||||||
setImageViewDark(dark, fade, com.android.internal.R.id.icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setImageViewDark(boolean dark, boolean fade, int imageViewId) {
|
|
||||||
// TODO: implement fade
|
|
||||||
final ImageView v = (ImageView) mContractedChild.findViewById(imageViewId);
|
|
||||||
if (v == null) return;
|
|
||||||
final Drawable d = v.getBackground();
|
|
||||||
if (dark) {
|
|
||||||
v.setLayerType(LAYER_TYPE_HARDWARE, INVERT_PAINT);
|
|
||||||
if (d != null) {
|
|
||||||
v.setTag(R.id.doze_saved_filter_tag, d.getColorFilter() != null ? d.getColorFilter()
|
|
||||||
: NO_COLOR_FILTER);
|
|
||||||
d.setColorFilter(getResources().getColor(R.color.doze_small_icon_background_color),
|
|
||||||
PorterDuff.Mode.SRC_ATOP);
|
|
||||||
v.setImageAlpha(getResources().getInteger(R.integer.doze_small_icon_alpha));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v.setLayerType(LAYER_TYPE_NONE, null);
|
|
||||||
if (d != null) {
|
|
||||||
final ColorFilter filter = (ColorFilter) v.getTag(R.id.doze_saved_filter_tag);
|
|
||||||
if (filter != null) {
|
|
||||||
d.setColorFilter(filter == NO_COLOR_FILTER ? null : filter);
|
|
||||||
v.setTag(R.id.doze_saved_filter_tag, null);
|
|
||||||
}
|
|
||||||
v.setImageAlpha(0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -290,16 +263,4 @@ public class NotificationContentView extends FrameLayout {
|
|||||||
// layout, and saves us some layers.
|
// layout, and saves us some layers.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Paint createInvertPaint() {
|
|
||||||
final Paint p = new Paint();
|
|
||||||
final float[] invert = {
|
|
||||||
-1f, 0f, 0f, 1f, 1f,
|
|
||||||
0f, -1f, 0f, 1f, 1f,
|
|
||||||
0f, 0f, -1f, 1f, 1f,
|
|
||||||
0f, 0f, 0f, 1f, 0f
|
|
||||||
};
|
|
||||||
p.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(invert)));
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.systemui.ViewInvertHelper;
|
||||||
|
import com.android.systemui.statusbar.phone.NotificationPanelView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a notification containing a custom view.
|
||||||
|
*/
|
||||||
|
public class NotificationCustomViewWrapper extends NotificationViewWrapper {
|
||||||
|
|
||||||
|
private final ViewInvertHelper mInvertHelper;
|
||||||
|
private boolean mDark;
|
||||||
|
|
||||||
|
protected NotificationCustomViewWrapper(View view) {
|
||||||
|
super(view);
|
||||||
|
mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDark(boolean dark, boolean fade, long delay) {
|
||||||
|
if (mDark != dark) {
|
||||||
|
mDark = dark;
|
||||||
|
if (fade) {
|
||||||
|
mInvertHelper.fade(dark, delay);
|
||||||
|
} else {
|
||||||
|
mInvertHelper.update(dark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a media notification.
|
||||||
|
*/
|
||||||
|
public class NotificationMediaViewWrapper extends NotificationTemplateViewWrapper {
|
||||||
|
|
||||||
|
private boolean mDark;
|
||||||
|
|
||||||
|
protected NotificationMediaViewWrapper(Context ctx, View view) {
|
||||||
|
super(ctx, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDark(boolean dark, boolean fade, long delay) {
|
||||||
|
if (mDark != dark) {
|
||||||
|
mDark = dark;
|
||||||
|
|
||||||
|
// Only update the large icon, because the rest is already inverted.
|
||||||
|
setPictureGrayscale(dark, fade, delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,8 @@ import android.util.AttributeSet;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.ViewInvertHelper;
|
||||||
|
import com.android.systemui.statusbar.phone.NotificationPanelView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container view for overflowing notification icons on Keyguard.
|
* Container view for overflowing notification icons on Keyguard.
|
||||||
@@ -28,6 +30,8 @@ import com.android.systemui.R;
|
|||||||
public class NotificationOverflowContainer extends ActivatableNotificationView {
|
public class NotificationOverflowContainer extends ActivatableNotificationView {
|
||||||
|
|
||||||
private NotificationOverflowIconsView mIconsView;
|
private NotificationOverflowIconsView mIconsView;
|
||||||
|
private ViewInvertHelper mViewInvertHelper;
|
||||||
|
private boolean mDark;
|
||||||
|
|
||||||
public NotificationOverflowContainer(Context context, AttributeSet attrs) {
|
public NotificationOverflowContainer(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
@@ -39,6 +43,20 @@ public class NotificationOverflowContainer extends ActivatableNotificationView {
|
|||||||
mIconsView = (NotificationOverflowIconsView) findViewById(R.id.overflow_icons_view);
|
mIconsView = (NotificationOverflowIconsView) findViewById(R.id.overflow_icons_view);
|
||||||
mIconsView.setMoreText((TextView) findViewById(R.id.more_text));
|
mIconsView.setMoreText((TextView) findViewById(R.id.more_text));
|
||||||
mIconsView.setOverflowIndicator(findViewById(R.id.more_icon_overflow));
|
mIconsView.setOverflowIndicator(findViewById(R.id.more_icon_overflow));
|
||||||
|
mViewInvertHelper = new ViewInvertHelper(findViewById(R.id.content),
|
||||||
|
NotificationPanelView.DOZE_ANIMATION_DURATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDark(boolean dark, boolean fade, long delay) {
|
||||||
|
super.setDark(dark, fade, delay);
|
||||||
|
if (mDark == dark) return;
|
||||||
|
mDark = dark;
|
||||||
|
if (fade) {
|
||||||
|
mViewInvertHelper.fade(dark, delay);
|
||||||
|
} else {
|
||||||
|
mViewInvertHelper.update(dark);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotificationOverflowIconsView getIconsView() {
|
public NotificationOverflowIconsView getIconsView() {
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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;
|
||||||
|
|
||||||
|
import android.animation.Animator;
|
||||||
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.ColorFilter;
|
||||||
|
import android.graphics.ColorMatrix;
|
||||||
|
import android.graphics.ColorMatrixColorFilter;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.PorterDuffColorFilter;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.animation.AnimationUtils;
|
||||||
|
import android.view.animation.Interpolator;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.ViewInvertHelper;
|
||||||
|
import com.android.systemui.statusbar.phone.NotificationPanelView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a notification view inflated from a template.
|
||||||
|
*/
|
||||||
|
public class NotificationTemplateViewWrapper extends NotificationViewWrapper {
|
||||||
|
|
||||||
|
private final ViewInvertHelper mInvertHelper;
|
||||||
|
private final ImageView mIcon;
|
||||||
|
protected final ImageView mPicture;
|
||||||
|
private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
|
||||||
|
private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter(
|
||||||
|
0, PorterDuff.Mode.SRC_ATOP);
|
||||||
|
private final int mIconDarkAlpha;
|
||||||
|
private final int mIconBackgroundColor;
|
||||||
|
private final int mIconBackgroundDarkColor;
|
||||||
|
private final Interpolator mLinearOutSlowInInterpolator;
|
||||||
|
|
||||||
|
private boolean mDark;
|
||||||
|
|
||||||
|
protected NotificationTemplateViewWrapper(Context ctx, View view) {
|
||||||
|
super(view);
|
||||||
|
mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
|
||||||
|
mIconBackgroundDarkColor =
|
||||||
|
ctx.getResources().getColor(R.color.doze_small_icon_background_color);
|
||||||
|
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(ctx,
|
||||||
|
android.R.interpolator.linear_out_slow_in);
|
||||||
|
View mainColumn = view.findViewById(com.android.internal.R.id.notification_main_column);
|
||||||
|
mInvertHelper = mainColumn != null
|
||||||
|
? new ViewInvertHelper(mainColumn, NotificationPanelView.DOZE_ANIMATION_DURATION)
|
||||||
|
: null;
|
||||||
|
ImageView largeIcon = (ImageView) view.findViewById(com.android.internal.R.id.icon);
|
||||||
|
ImageView rightIcon = (ImageView) view.findViewById(com.android.internal.R.id.right_icon);
|
||||||
|
mIcon = resolveIcon(largeIcon, rightIcon);
|
||||||
|
mPicture = resolvePicture(largeIcon);
|
||||||
|
mIconBackgroundColor = resolveBackgroundColor(mIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageView resolveIcon(ImageView largeIcon, ImageView rightIcon) {
|
||||||
|
return largeIcon != null && largeIcon.getBackground() != null ? largeIcon
|
||||||
|
: rightIcon != null && rightIcon.getBackground() != null ? rightIcon
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ImageView resolvePicture(ImageView largeIcon) {
|
||||||
|
return largeIcon != null && largeIcon.getBackground() == null
|
||||||
|
? largeIcon
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int resolveBackgroundColor(ImageView icon) {
|
||||||
|
if (icon != null && icon.getBackground() != null) {
|
||||||
|
ColorFilter filter = icon.getBackground().getColorFilter();
|
||||||
|
if (filter instanceof PorterDuffColorFilter) {
|
||||||
|
return ((PorterDuffColorFilter) filter).getColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDark(boolean dark, boolean fade, long delay) {
|
||||||
|
if (mDark != dark) {
|
||||||
|
mDark = dark;
|
||||||
|
if (mInvertHelper != null) {
|
||||||
|
if (fade) {
|
||||||
|
mInvertHelper.fade(dark, delay);
|
||||||
|
} else {
|
||||||
|
mInvertHelper.update(dark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mIcon != null) {
|
||||||
|
if (fade) {
|
||||||
|
fadeIconColorFilter(mIcon, dark, delay);
|
||||||
|
fadeIconAlpha(mIcon, dark, delay);
|
||||||
|
} else {
|
||||||
|
updateIconColorFilter(mIcon, dark);
|
||||||
|
updateIconAlpha(mIcon, dark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setPictureGrayscale(dark, fade, delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setPictureGrayscale(boolean grayscale, boolean fade, long delay) {
|
||||||
|
if (mPicture != null) {
|
||||||
|
if (fade) {
|
||||||
|
fadeGrayscale(mPicture, grayscale, delay);
|
||||||
|
} else {
|
||||||
|
updateGrayscale(mPicture, grayscale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
|
||||||
|
boolean dark, long delay, Animator.AnimatorListener listener) {
|
||||||
|
float startIntensity = dark ? 0f : 1f;
|
||||||
|
float endIntensity = dark ? 1f : 0f;
|
||||||
|
ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
|
||||||
|
animator.addUpdateListener(updateListener);
|
||||||
|
animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
|
||||||
|
animator.setInterpolator(mLinearOutSlowInInterpolator);
|
||||||
|
animator.setStartDelay(delay);
|
||||||
|
if (listener != null) {
|
||||||
|
animator.addListener(listener);
|
||||||
|
}
|
||||||
|
animator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fadeIconColorFilter(final ImageView target, boolean dark, long delay) {
|
||||||
|
startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
updateIconColorFilter(target, (Float) animation.getAnimatedValue());
|
||||||
|
}
|
||||||
|
}, dark, delay, null /* listener */);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fadeIconAlpha(final ImageView target, boolean dark, long delay) {
|
||||||
|
startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
float t = (float) animation.getAnimatedValue();
|
||||||
|
target.setImageAlpha((int) (255 * (1f - t) + mIconDarkAlpha * t));
|
||||||
|
}
|
||||||
|
}, dark, delay, null /* listener */);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
|
||||||
|
startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationUpdate(ValueAnimator animation) {
|
||||||
|
updateGrayscaleMatrix((float) animation.getAnimatedValue());
|
||||||
|
target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
|
||||||
|
}
|
||||||
|
}, dark, delay, new AnimatorListenerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
if (!dark) {
|
||||||
|
target.setColorFilter(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateIconColorFilter(ImageView target, boolean dark) {
|
||||||
|
updateIconColorFilter(target, dark ? 1f : 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateIconColorFilter(ImageView target, float intensity) {
|
||||||
|
int color = interpolateColor(mIconBackgroundColor, mIconBackgroundDarkColor, intensity);
|
||||||
|
mIconColorFilter.setColor(color);
|
||||||
|
target.getBackground().mutate().setColorFilter(mIconColorFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateIconAlpha(ImageView target, boolean dark) {
|
||||||
|
target.setImageAlpha(dark ? mIconDarkAlpha : 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateGrayscale(ImageView target, boolean dark) {
|
||||||
|
if (dark) {
|
||||||
|
updateGrayscaleMatrix(1f);
|
||||||
|
target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
|
||||||
|
} else {
|
||||||
|
target.setColorFilter(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateGrayscaleMatrix(float intensity) {
|
||||||
|
mGrayscaleColorMatrix.setSaturation(1 - intensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int interpolateColor(int source, int target, float t) {
|
||||||
|
int aSource = Color.alpha(source);
|
||||||
|
int rSource = Color.red(source);
|
||||||
|
int gSource = Color.green(source);
|
||||||
|
int bSource = Color.blue(source);
|
||||||
|
int aTarget = Color.alpha(target);
|
||||||
|
int rTarget = Color.red(target);
|
||||||
|
int gTarget = Color.green(target);
|
||||||
|
int bTarget = Color.blue(target);
|
||||||
|
return Color.argb(
|
||||||
|
(int) (aSource * (1f - t) + aTarget * t),
|
||||||
|
(int) (rSource * (1f - t) + rTarget * t),
|
||||||
|
(int) (gSource * (1f - t) + gTarget * t),
|
||||||
|
(int) (bSource * (1f - t) + bTarget * t));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 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;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps the actual notification content view; used to implement behaviors which are different for
|
||||||
|
* the individual templates and custom views.
|
||||||
|
*/
|
||||||
|
public abstract class NotificationViewWrapper {
|
||||||
|
|
||||||
|
protected final View mView;
|
||||||
|
|
||||||
|
public static NotificationViewWrapper wrap(Context ctx, View v) {
|
||||||
|
|
||||||
|
// TODO: Figure out a better way to find out which template the view is.
|
||||||
|
if (v.findViewById(com.android.internal.R.id.media_actions) != null) {
|
||||||
|
return new NotificationMediaViewWrapper(ctx, v);
|
||||||
|
} else if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
|
||||||
|
return new NotificationTemplateViewWrapper(ctx, v);
|
||||||
|
} else {
|
||||||
|
return new NotificationCustomViewWrapper(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NotificationViewWrapper(View view) {
|
||||||
|
mView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In dark mode, we draw as little as possible, assuming a black background.
|
||||||
|
*
|
||||||
|
* @param dark whether we should display ourselves in dark mode
|
||||||
|
* @param fade whether to animate the transition if the mode changes
|
||||||
|
* @param delay if fading, the delay of the animation
|
||||||
|
*/
|
||||||
|
public abstract void setDark(boolean dark, boolean fade, long delay);
|
||||||
|
}
|
||||||
@@ -3708,14 +3708,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
|||||||
if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) {
|
if (mState != StatusBarState.KEYGUARD && !mNotificationPanel.isDozing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mNotificationPanel.setDozing(mDozing, mDozeScrimController.isPulsing() /*animate*/);
|
boolean animate = !mDozing && mDozeScrimController.isPulsing();
|
||||||
if (mDozing) {
|
mNotificationPanel.setDozing(mDozing, animate);
|
||||||
mStackScroller.setDark(true, false /*animate*/);
|
mStackScroller.setDark(mDozing, animate);
|
||||||
} else {
|
|
||||||
mStackScroller.setDark(false, false /*animate*/);
|
|
||||||
}
|
|
||||||
mScrimController.setDozing(mDozing);
|
mScrimController.setDozing(mDozing);
|
||||||
mDozeScrimController.setDozing(mDozing, mDozeScrimController.isPulsing() /* animate */);
|
mDozeScrimController.setDozing(mDozing, animate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateStackScrollerState(boolean goingToFullShade) {
|
public void updateStackScrollerState(boolean goingToFullShade) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class AnimationFilter {
|
|||||||
boolean animateHideSensitive;
|
boolean animateHideSensitive;
|
||||||
boolean hasDelays;
|
boolean hasDelays;
|
||||||
boolean hasGoToFullShadeEvent;
|
boolean hasGoToFullShadeEvent;
|
||||||
|
boolean hasDarkEvent;
|
||||||
|
|
||||||
public AnimationFilter animateAlpha() {
|
public AnimationFilter animateAlpha() {
|
||||||
animateAlpha = true;
|
animateAlpha = true;
|
||||||
@@ -98,6 +99,10 @@ public class AnimationFilter {
|
|||||||
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) {
|
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) {
|
||||||
hasGoToFullShadeEvent = true;
|
hasGoToFullShadeEvent = true;
|
||||||
}
|
}
|
||||||
|
if (events.get(i).animationType ==
|
||||||
|
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_DARK) {
|
||||||
|
hasDarkEvent = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,5 +131,6 @@ public class AnimationFilter {
|
|||||||
animateHideSensitive = false;
|
animateHideSensitive = false;
|
||||||
hasDelays = false;
|
hasDelays = false;
|
||||||
hasGoToFullShadeEvent = false;
|
hasGoToFullShadeEvent = false;
|
||||||
|
hasDarkEvent = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2455,7 +2455,8 @@ public class NotificationStackScrollLayout extends ViewGroup
|
|||||||
|
|
||||||
// ANIMATION_TYPE_DARK
|
// ANIMATION_TYPE_DARK
|
||||||
new AnimationFilter()
|
new AnimationFilter()
|
||||||
.animateDark(),
|
.animateDark()
|
||||||
|
.hasDelays(),
|
||||||
|
|
||||||
// ANIMATION_TYPE_GO_TO_FULL_SHADE
|
// ANIMATION_TYPE_GO_TO_FULL_SHADE
|
||||||
new AnimationFilter()
|
new AnimationFilter()
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ public class StackScrollState {
|
|||||||
child.setDimmed(state.dimmed, false /* animate */);
|
child.setDimmed(state.dimmed, false /* animate */);
|
||||||
|
|
||||||
// apply dark
|
// apply dark
|
||||||
child.setDark(state.dark, false /* animate */);
|
child.setDark(state.dark, false /* animate */, 0 /* delay */);
|
||||||
|
|
||||||
// apply hiding sensitive
|
// apply hiding sensitive
|
||||||
child.setHideSensitive(
|
child.setHideSensitive(
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class StackStateAnimator {
|
|||||||
public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80;
|
public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80;
|
||||||
public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32;
|
public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32;
|
||||||
public static final int ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE = 48;
|
public static final int ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE = 48;
|
||||||
|
public static final int ANIMATION_DELAY_PER_ELEMENT_DARK = 24;
|
||||||
private static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
|
private static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
|
||||||
|
|
||||||
private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
|
private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
|
||||||
@@ -161,11 +162,12 @@ public class StackStateAnimator {
|
|||||||
boolean scaleChanging = child.getScaleX() != viewState.scale;
|
boolean scaleChanging = child.getScaleX() != viewState.scale;
|
||||||
boolean alphaChanging = alpha != child.getAlpha();
|
boolean alphaChanging = alpha != child.getAlpha();
|
||||||
boolean heightChanging = viewState.height != child.getActualHeight();
|
boolean heightChanging = viewState.height != child.getActualHeight();
|
||||||
|
boolean darkChanging = viewState.dark != child.isDark();
|
||||||
boolean topInsetChanging = viewState.clipTopAmount != child.getClipTopAmount();
|
boolean topInsetChanging = viewState.clipTopAmount != child.getClipTopAmount();
|
||||||
boolean wasAdded = mNewAddChildren.contains(child);
|
boolean wasAdded = mNewAddChildren.contains(child);
|
||||||
boolean hasDelays = mAnimationFilter.hasDelays;
|
boolean hasDelays = mAnimationFilter.hasDelays;
|
||||||
boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || scaleChanging ||
|
boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || scaleChanging ||
|
||||||
alphaChanging || heightChanging || topInsetChanging;
|
alphaChanging || heightChanging || topInsetChanging || darkChanging;
|
||||||
boolean noAnimation = wasAdded;
|
boolean noAnimation = wasAdded;
|
||||||
long delay = 0;
|
long delay = 0;
|
||||||
long duration = mCurrentLength;
|
long duration = mCurrentLength;
|
||||||
@@ -242,7 +244,7 @@ public class StackStateAnimator {
|
|||||||
&& !noAnimation);
|
&& !noAnimation);
|
||||||
|
|
||||||
// start dark animation
|
// start dark animation
|
||||||
child.setDark(viewState.dark, mAnimationFilter.animateDark && !noAnimation);
|
child.setDark(viewState.dark, mAnimationFilter.animateDark && !noAnimation, delay);
|
||||||
|
|
||||||
// apply speed bump state
|
// apply speed bump state
|
||||||
child.setBelowSpeedBump(viewState.belowSpeedBump);
|
child.setBelowSpeedBump(viewState.belowSpeedBump);
|
||||||
@@ -262,6 +264,9 @@ public class StackStateAnimator {
|
|||||||
|
|
||||||
private long calculateChildAnimationDelay(StackScrollState.ViewState viewState,
|
private long calculateChildAnimationDelay(StackScrollState.ViewState viewState,
|
||||||
StackScrollState finalState) {
|
StackScrollState finalState) {
|
||||||
|
if (mAnimationFilter.hasDarkEvent) {
|
||||||
|
return calculateDelayDark(viewState);
|
||||||
|
}
|
||||||
if (mAnimationFilter.hasGoToFullShadeEvent) {
|
if (mAnimationFilter.hasGoToFullShadeEvent) {
|
||||||
return calculateDelayGoToFullShade(viewState);
|
return calculateDelayGoToFullShade(viewState);
|
||||||
}
|
}
|
||||||
@@ -309,6 +314,10 @@ public class StackStateAnimator {
|
|||||||
return minDelay;
|
return minDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long calculateDelayDark(StackScrollState.ViewState viewState) {
|
||||||
|
return viewState.notGoneIndex * ANIMATION_DELAY_PER_ELEMENT_DARK;
|
||||||
|
}
|
||||||
|
|
||||||
private long calculateDelayGoToFullShade(StackScrollState.ViewState viewState) {
|
private long calculateDelayGoToFullShade(StackScrollState.ViewState viewState) {
|
||||||
float index = viewState.notGoneIndex;
|
float index = viewState.notGoneIndex;
|
||||||
index = (float) Math.pow(index, 0.7f);
|
index = (float) Math.pow(index, 0.7f);
|
||||||
|
|||||||
Reference in New Issue
Block a user