summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJorim Jaggi <jjaggi@google.com>2014-08-05 16:22:30 +0200
committerJorim Jaggi <jjaggi@google.com>2014-08-05 16:38:02 +0200
commita2052ea218386877e6d5d2136483a62b2b31f774 (patch)
tree4b933b155795ab6abb280b9aff74438ea91074d9
parentf479792e05485a536c3fa68db9d8a71f34591b78 (diff)
downloadframeworks_base-a2052ea218386877e6d5d2136483a62b2b31f774.zip
frameworks_base-a2052ea218386877e6d5d2136483a62b2b31f774.tar.gz
frameworks_base-a2052ea218386877e6d5d2136483a62b2b31f774.tar.bz2
Empty notification shade state.
Bug: 16483230 Change-Id: I7953a7954cae12124146f462ed8c0dc44769a38f
-rw-r--r--packages/SystemUI/res/layout/status_bar_no_notifications.xml33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java122
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java37
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java152
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java6
9 files changed, 302 insertions, 122 deletions
diff --git a/packages/SystemUI/res/layout/status_bar_no_notifications.xml b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
new file mode 100644
index 0000000..dd501d4
--- /dev/null
+++ b/packages/SystemUI/res/layout/status_bar_no_notifications.xml
@@ -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>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index c2f6aa4..af92e49 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -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) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
index f674b06..897dbf2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
@@ -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();
- }
-
- @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;
+ protected View findContentView() {
+ return findViewById(R.id.dismiss_text);
}
- public void setWillBeGone(boolean willBeGone) {
- mWillBeGone = willBeGone;
+ public void setOnButtonClickListener(OnClickListener listener) {
+ mContent.setOnClickListener(listener);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
new file mode 100644
index 0000000..582d165
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -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);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
new file mode 100644
index 0000000..62a492e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
@@ -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();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 53c4740..98bb591 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -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);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 8dfed92..ae7d500 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -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;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 943ee21..fcca5fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -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;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index a174952..f7a2824 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -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());
}
}
}