am dafe07eb: am 1073027b: am a7a0e608: Merge "Empty notification shade state." into lmp-dev
* commit 'dafe07eb240fd1b9e385c3a0be8fc8b7da2d4243': Empty notification shade state.
This commit is contained in:
33
packages/SystemUI/res/layout/status_bar_no_notifications.xml
Normal file
33
packages/SystemUI/res/layout/status_bar_no_notifications.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<!--
|
||||
~ 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
|
||||
-->
|
||||
|
||||
<!-- Extends Framelayout -->
|
||||
<com.android.systemui.statusbar.EmptyShadeView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
>
|
||||
<TextView
|
||||
android:id="@+id/no_notifications"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:paddingTop="12dp"
|
||||
android:gravity="top|center_horizontal"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="20sp"
|
||||
android:text="@string/empty_shade_text"/>
|
||||
</com.android.systemui.statusbar.EmptyShadeView>
|
||||
@@ -200,6 +200,7 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
|
||||
protected NotificationOverflowContainer mKeyguardIconOverflowContainer;
|
||||
protected DismissView mDismissView;
|
||||
protected EmptyShadeView mEmptyShadeView;
|
||||
|
||||
@Override // NotificationData.Environment
|
||||
public boolean isDeviceProvisioned() {
|
||||
@@ -1405,12 +1406,11 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
} else {
|
||||
mKeyguardIconOverflowContainer.setVisibility(View.GONE);
|
||||
}
|
||||
// Move overflow container to second last position.
|
||||
mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer,
|
||||
mStackScroller.getChildCount() - 2);
|
||||
|
||||
// Now move dismissView to the last position.
|
||||
mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1);
|
||||
mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer,
|
||||
mStackScroller.getChildCount() - 3);
|
||||
mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 2);
|
||||
mStackScroller.changeViewPosition(mEmptyShadeView, mStackScroller.getChildCount() - 1);
|
||||
}
|
||||
|
||||
private boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
|
||||
|
||||
@@ -19,133 +19,21 @@ package com.android.systemui.statusbar;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
|
||||
public class DismissView extends ExpandableView {
|
||||
|
||||
private View mClearAllIcon;
|
||||
private boolean mIsVisible;
|
||||
private boolean mAnimating;
|
||||
private boolean mWillBeGone;
|
||||
public class DismissView extends StackScrollerDecorView {
|
||||
|
||||
public DismissView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mClearAllIcon = findViewById(R.id.dismiss_text);
|
||||
setInvisible();
|
||||
protected View findContentView() {
|
||||
return findViewById(R.id.dismiss_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
setOutlineProvider(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTransparent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void performVisibilityAnimation(boolean nowVisible) {
|
||||
animateText(nowVisible, null /* onFinishedRunnable */);
|
||||
}
|
||||
|
||||
public void performVisibilityAnimation(boolean nowVisible, Runnable onFinishedRunnable) {
|
||||
animateText(nowVisible, onFinishedRunnable);
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return mIsVisible || mAnimating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate the text to a new visibility.
|
||||
*
|
||||
* @param nowVisible should it now be visible
|
||||
* @param onFinishedRunnable A runnable which should be run when the animation is
|
||||
* finished.
|
||||
*/
|
||||
private void animateText(boolean nowVisible, final Runnable onFinishedRunnable) {
|
||||
if (nowVisible != mIsVisible) {
|
||||
// Animate text
|
||||
float endValue = nowVisible ? 1.0f : 0.0f;
|
||||
Interpolator interpolator;
|
||||
if (nowVisible) {
|
||||
interpolator = PhoneStatusBar.ALPHA_IN;
|
||||
} else {
|
||||
interpolator = PhoneStatusBar.ALPHA_OUT;
|
||||
}
|
||||
mAnimating = true;
|
||||
mClearAllIcon.animate()
|
||||
.alpha(endValue)
|
||||
.setInterpolator(interpolator)
|
||||
.setDuration(260)
|
||||
.withLayer()
|
||||
.withEndAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mAnimating = false;
|
||||
if (onFinishedRunnable != null) {
|
||||
onFinishedRunnable.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
mIsVisible = nowVisible;
|
||||
} else {
|
||||
if (onFinishedRunnable != null) {
|
||||
onFinishedRunnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setInvisible() {
|
||||
mClearAllIcon.setAlpha(0.0f);
|
||||
mIsVisible = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performRemoveAnimation(long duration, float translationDirection,
|
||||
Runnable onFinishedRunnable) {
|
||||
// TODO: Use duration
|
||||
performVisibilityAnimation(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAddAnimation(long delay, long duration) {
|
||||
// TODO: use delay and duration
|
||||
performVisibilityAnimation(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScrimAmount(float scrimAmount) {
|
||||
// We don't need to scrim the dismissView
|
||||
}
|
||||
|
||||
public void setOnButtonClickListener(OnClickListener onClickListener) {
|
||||
mClearAllIcon.setOnClickListener(onClickListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void cancelAnimation() {
|
||||
mClearAllIcon.animate().cancel();
|
||||
}
|
||||
|
||||
public boolean willBeGone() {
|
||||
return mWillBeGone;
|
||||
}
|
||||
|
||||
public void setWillBeGone(boolean willBeGone) {
|
||||
mWillBeGone = willBeGone;
|
||||
public void setOnButtonClickListener(OnClickListener listener) {
|
||||
mContent.setOnClickListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
|
||||
public class EmptyShadeView extends StackScrollerDecorView {
|
||||
|
||||
public EmptyShadeView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View findContentView() {
|
||||
return findViewById(R.id.no_notifications);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.systemui.statusbar.phone.PhoneStatusBar;
|
||||
|
||||
/**
|
||||
* A common base class for all views in the notification stack scroller which don't have a
|
||||
* background.
|
||||
*/
|
||||
public abstract class StackScrollerDecorView extends ExpandableView {
|
||||
|
||||
protected View mContent;
|
||||
private boolean mIsVisible;
|
||||
private boolean mAnimating;
|
||||
private boolean mWillBeGone;
|
||||
|
||||
public StackScrollerDecorView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mContent = findContentView();
|
||||
setInvisible();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
setOutlineProvider(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTransparent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void performVisibilityAnimation(boolean nowVisible) {
|
||||
animateText(nowVisible, null /* onFinishedRunnable */);
|
||||
}
|
||||
|
||||
public void performVisibilityAnimation(boolean nowVisible, Runnable onFinishedRunnable) {
|
||||
animateText(nowVisible, onFinishedRunnable);
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return mIsVisible || mAnimating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate the text to a new visibility.
|
||||
*
|
||||
* @param nowVisible should it now be visible
|
||||
* @param onFinishedRunnable A runnable which should be run when the animation is
|
||||
* finished.
|
||||
*/
|
||||
private void animateText(boolean nowVisible, final Runnable onFinishedRunnable) {
|
||||
if (nowVisible != mIsVisible) {
|
||||
// Animate text
|
||||
float endValue = nowVisible ? 1.0f : 0.0f;
|
||||
Interpolator interpolator;
|
||||
if (nowVisible) {
|
||||
interpolator = PhoneStatusBar.ALPHA_IN;
|
||||
} else {
|
||||
interpolator = PhoneStatusBar.ALPHA_OUT;
|
||||
}
|
||||
mAnimating = true;
|
||||
mContent.animate()
|
||||
.alpha(endValue)
|
||||
.setInterpolator(interpolator)
|
||||
.setDuration(260)
|
||||
.withLayer()
|
||||
.withEndAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mAnimating = false;
|
||||
if (onFinishedRunnable != null) {
|
||||
onFinishedRunnable.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
mIsVisible = nowVisible;
|
||||
} else {
|
||||
if (onFinishedRunnable != null) {
|
||||
onFinishedRunnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setInvisible() {
|
||||
mContent.setAlpha(0.0f);
|
||||
mIsVisible = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performRemoveAnimation(long duration, float translationDirection,
|
||||
Runnable onFinishedRunnable) {
|
||||
// TODO: Use duration
|
||||
performVisibilityAnimation(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAddAnimation(long delay, long duration) {
|
||||
// TODO: use delay and duration
|
||||
performVisibilityAnimation(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScrimAmount(float scrimAmount) {
|
||||
// We don't need to scrim the dismissView
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void cancelAnimation() {
|
||||
mContent.animate().cancel();
|
||||
}
|
||||
|
||||
public boolean willBeGone() {
|
||||
return mWillBeGone;
|
||||
}
|
||||
|
||||
public void setWillBeGone(boolean willBeGone) {
|
||||
mWillBeGone = willBeGone;
|
||||
}
|
||||
|
||||
protected abstract View findContentView();
|
||||
}
|
||||
@@ -147,6 +147,8 @@ public class NotificationPanelView extends PanelView implements
|
||||
private boolean mHeaderAnimatingIn;
|
||||
private ObjectAnimator mQsContainerAnimator;
|
||||
|
||||
private boolean mShadeEmpty;
|
||||
|
||||
public NotificationPanelView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mSystemIconsCopy = new MirrorView(context);
|
||||
@@ -879,6 +881,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
mQsContainer.setVisibility(
|
||||
mKeyguardShowing && !expandVisually ? View.INVISIBLE : View.VISIBLE);
|
||||
mScrollView.setTouchEnabled(mQsExpanded);
|
||||
updateEmptyShadeView();
|
||||
}
|
||||
|
||||
private void setQsExpansion(float height) {
|
||||
@@ -1615,4 +1618,15 @@ public class NotificationPanelView extends PanelView implements
|
||||
}
|
||||
updateKeyguardStatusBarVisibility();
|
||||
}
|
||||
|
||||
public void setShadeEmpty(boolean shadeEmpty) {
|
||||
mShadeEmpty = shadeEmpty;
|
||||
updateEmptyShadeView();
|
||||
}
|
||||
|
||||
private void updateEmptyShadeView() {
|
||||
|
||||
// Hide "No notifications" in QS.
|
||||
mNotificationStackScroller.updateEmptyShadeView(mShadeEmpty && !mQsExpanded);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ import com.android.systemui.statusbar.BaseStatusBar;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.DismissView;
|
||||
import com.android.systemui.statusbar.DragDownHelper;
|
||||
import com.android.systemui.statusbar.EmptyShadeView;
|
||||
import com.android.systemui.statusbar.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.GestureRecorder;
|
||||
import com.android.systemui.statusbar.KeyguardIndicationController;
|
||||
@@ -696,6 +697,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
}
|
||||
});
|
||||
mStackScroller.setDismissView(mDismissView);
|
||||
mEmptyShadeView = (EmptyShadeView) LayoutInflater.from(mContext).inflate(
|
||||
R.layout.status_bar_no_notifications, mStackScroller, false);
|
||||
mStackScroller.setEmptyShadeView(mEmptyShadeView);
|
||||
mExpandedContents = mStackScroller;
|
||||
|
||||
mScrimController = new ScrimController(mStatusBarWindow.findViewById(R.id.scrim_behind),
|
||||
@@ -1420,6 +1424,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
updateRowStates();
|
||||
updateSpeedbump();
|
||||
updateClearAll();
|
||||
updateEmptyShadeView();
|
||||
|
||||
mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned() && mUserSetup);
|
||||
mShadeUpdates.check();
|
||||
@@ -1432,6 +1437,13 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
||||
mStackScroller.updateDismissView(showDismissView);
|
||||
}
|
||||
|
||||
private void updateEmptyShadeView() {
|
||||
boolean showEmptyShade =
|
||||
mState != StatusBarState.KEYGUARD &&
|
||||
mNotificationData.getActiveNotifications().size() == 0;
|
||||
mNotificationPanel.setShadeEmpty(showEmptyShade);
|
||||
}
|
||||
|
||||
private void updateSpeedbump() {
|
||||
int speedbumpIndex = -1;
|
||||
int currentIndex = 0;
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.SwipeHelper;
|
||||
import com.android.systemui.statusbar.ActivatableNotificationView;
|
||||
import com.android.systemui.statusbar.DismissView;
|
||||
import com.android.systemui.statusbar.EmptyShadeView;
|
||||
import com.android.systemui.statusbar.ExpandableNotificationRow;
|
||||
import com.android.systemui.statusbar.ExpandableView;
|
||||
import com.android.systemui.statusbar.SpeedBumpView;
|
||||
@@ -145,6 +146,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
private boolean mExpandedInThisMotion;
|
||||
private boolean mScrollingEnabled;
|
||||
private DismissView mDismissView;
|
||||
private EmptyShadeView mEmptyShadeView;
|
||||
private boolean mDismissAllInProgress;
|
||||
|
||||
/**
|
||||
@@ -1222,6 +1224,9 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
if (mDismissView.willBeGone()) {
|
||||
count--;
|
||||
}
|
||||
if (mEmptyShadeView.willBeGone()) {
|
||||
count--;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -1985,6 +1990,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
public void goToFullShade(long delay) {
|
||||
updateSpeedBump(true /* visibility */);
|
||||
mDismissView.setInvisible();
|
||||
mEmptyShadeView.setInvisible();
|
||||
mGoToFullShadeNeedsAnimation = true;
|
||||
mGoToFullShadeDelay = delay;
|
||||
mNeedsAnimation = true;
|
||||
@@ -2039,6 +2045,38 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
addView(mDismissView);
|
||||
}
|
||||
|
||||
public void setEmptyShadeView(EmptyShadeView emptyShadeView) {
|
||||
mEmptyShadeView = emptyShadeView;
|
||||
addView(mEmptyShadeView);
|
||||
}
|
||||
|
||||
public void updateEmptyShadeView(boolean visible) {
|
||||
int oldVisibility = mEmptyShadeView.willBeGone() ? GONE : mEmptyShadeView.getVisibility();
|
||||
int newVisibility = visible ? VISIBLE : GONE;
|
||||
if (oldVisibility != newVisibility) {
|
||||
if (oldVisibility == GONE) {
|
||||
if (mEmptyShadeView.willBeGone()) {
|
||||
mEmptyShadeView.cancelAnimation();
|
||||
} else {
|
||||
mEmptyShadeView.setInvisible();
|
||||
mEmptyShadeView.setVisibility(newVisibility);
|
||||
}
|
||||
mEmptyShadeView.setWillBeGone(false);
|
||||
updateContentHeight();
|
||||
} else {
|
||||
mEmptyShadeView.setWillBeGone(true);
|
||||
mEmptyShadeView.performVisibilityAnimation(false, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mEmptyShadeView.setVisibility(GONE);
|
||||
mEmptyShadeView.setWillBeGone(false);
|
||||
updateContentHeight();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateDismissView(boolean visible) {
|
||||
int oldVisibility = mDismissView.willBeGone() ? GONE : mDismissView.getVisibility();
|
||||
int newVisibility = visible ? VISIBLE : GONE;
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.view.ViewGroup;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.DismissView;
|
||||
import com.android.systemui.statusbar.EmptyShadeView;
|
||||
import com.android.systemui.statusbar.ExpandableView;
|
||||
import com.android.systemui.statusbar.SpeedBumpView;
|
||||
|
||||
@@ -180,6 +181,11 @@ public class StackScrollState {
|
||||
DismissView dismissView = (DismissView) child;
|
||||
boolean visible = state.topOverLap < mClearAllTopPadding;
|
||||
dismissView.performVisibilityAnimation(visible && !dismissView.willBeGone());
|
||||
} else if (child instanceof EmptyShadeView) {
|
||||
EmptyShadeView emptyShadeView = (EmptyShadeView) child;
|
||||
boolean visible = state.topOverLap <= 0;
|
||||
emptyShadeView.performVisibilityAnimation(
|
||||
visible && !emptyShadeView.willBeGone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user