diff options
10 files changed, 130 insertions, 48 deletions
diff --git a/packages/SystemUI/res/layout/qs_customize_panel.xml b/packages/SystemUI/res/layout/qs_customize_panel.xml index 582ad48c189e..0491ea08525d 100644 --- a/packages/SystemUI/res/layout/qs_customize_panel.xml +++ b/packages/SystemUI/res/layout/qs_customize_panel.xml @@ -14,10 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. --> + +<!-- Height is 0 because it will be managed by the QSContainer manually --> <com.android.systemui.qs.customize.QSCustomizer xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent" + android:layout_height="0dp" android:orientation="vertical" android:background="@drawable/qs_customizer_background" android:gravity="center_horizontal"> diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml index 994d3c943671..ef15195b5f71 100644 --- a/packages/SystemUI/res/layout/qs_panel.xml +++ b/packages/SystemUI/res/layout/qs_panel.xml @@ -34,4 +34,7 @@ <include android:id="@+id/qs_detail" layout="@layout/qs_detail" /> + <include android:id="@+id/qs_customize" layout="@layout/qs_customize_panel" + android:visibility="gone" /> + </com.android.systemui.qs.QSContainer> diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 656941f8b725..ccefb5fe0a5b 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -43,8 +43,10 @@ android:id="@+id/qs_density_container" android:layout="@layout/qs_panel" android:layout_width="@dimen/notification_panel_width" - android:layout_height="wrap_content" - android:layout_gravity="@integer/notification_panel_layout_gravity" /> + android:layout_height="match_parent" + android:layout_gravity="@integer/notification_panel_layout_gravity" + android:clipToPadding="false" + android:clipChildren="false" /> <com.android.systemui.statusbar.stack.NotificationStackScrollLayout android:id="@+id/notification_stack_scroller" diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java index c0c1e4d24359..5b05e84928fb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java @@ -19,6 +19,7 @@ package com.android.systemui.qs; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.content.Context; +import android.graphics.Point; import android.util.AttributeSet; import android.util.Log; import android.view.View; @@ -26,7 +27,9 @@ import android.view.ViewTreeObserver; import android.widget.FrameLayout; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.qs.customize.QSCustomizer; import com.android.systemui.statusbar.phone.BaseStatusBarHeader; +import com.android.systemui.statusbar.phone.NotificationPanelView; import com.android.systemui.statusbar.phone.QSTileHost; import com.android.systemui.statusbar.stack.StackStateAnimator; @@ -39,6 +42,8 @@ public class QSContainer extends FrameLayout { private static final String TAG = "QSContainer"; private static final boolean DEBUG = false; + private final Point mSizePoint = new Point(); + private int mHeightOverride = -1; private QSPanel mQSPanel; private QSDetail mQSDetail; @@ -51,6 +56,8 @@ public class QSContainer extends FrameLayout { private long mDelay; private QSAnimator mQSAnimator; + private QSCustomizer mQSCustomizer; + private NotificationPanelView mPanelView; public QSContainer(Context context, AttributeSet attrs) { super(context, attrs); @@ -65,21 +72,33 @@ public class QSContainer extends FrameLayout { mHeader = (BaseStatusBarHeader) findViewById(R.id.header); mQSAnimator = new QSAnimator(this, (QuickQSPanel) mHeader.findViewById(R.id.quick_qs_panel), mQSPanel); + mQSCustomizer = (QSCustomizer) findViewById(R.id.qs_customize); + mQSCustomizer.setQsContainer(this); } public void setHost(QSTileHost qsh) { - mQSPanel.setHost(qsh); + mQSPanel.setHost(qsh, mQSCustomizer); mHeader.setQSPanel(mQSPanel); mQSDetail.setHost(qsh); mQSAnimator.setHost(qsh); } + public void setPanelView(NotificationPanelView panelView) { + mPanelView = panelView; + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Since we control our own bottom, be whatever size we want. // Otherwise the QSPanel ends up with 0 height when the window is only the // size of the status bar. super.onMeasure(widthMeasureSpec, MeasureSpec.UNSPECIFIED); + + // QSCustomizer is always be the height of the screen, but do this after + // other measuring to avoid changing the height of the QSContainer. + getDisplay().getRealSize(mSizePoint); + mQSCustomizer.measure(widthMeasureSpec, + MeasureSpec.makeMeasureSpec(mSizePoint.y, MeasureSpec.EXACTLY)); } @Override @@ -88,6 +107,10 @@ public class QSContainer extends FrameLayout { updateBottom(); } + public boolean isCustomizing() { + return mQSCustomizer.isCustomizing(); + } + /** * Overrides the height of this view (post-layout), so that the content is clipped to that * height and the background is set to that height. @@ -104,6 +127,9 @@ public class QSContainer extends FrameLayout { * during closing the detail panel, this already returns the smaller height. */ public int getDesiredHeight() { + if (isCustomizing()) { + return getHeight(); + } if (mQSDetail.isClosingDetail()) { return mQSPanel.getGridHeight() + mHeader.getCollapsedHeight() + getPaddingBottom(); } else { @@ -111,9 +137,18 @@ public class QSContainer extends FrameLayout { } } + public void notifyCustomizeChanged() { + // The customize state changed, so our height changed. + updateBottom(); + // Let the panel know the position changed and it needs to update where notifications + // and whatnot are. + mPanelView.onQsHeightChanged(); + } + private void updateBottom() { int heightOverride = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight(); - int height = (int) (mQsExpansion * (heightOverride - mHeader.getCollapsedHeight())) + int height = mQSCustomizer.isCustomizing() ? mQSCustomizer.getHeight() + : (int) (mQsExpansion * (heightOverride - mHeader.getCollapsedHeight())) + mHeader.getCollapsedHeight(); setBottom(getTop() + height); mQSDetail.setBottom(getTop() + height); @@ -138,6 +173,10 @@ public class QSContainer extends FrameLayout { return mQSPanel; } + public QSCustomizer getCustomizer() { + return mQSCustomizer; + } + public boolean isShowingDetail() { return mQSPanel.isShowingCustomize() || mQSDetail.isShowingDetail(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 71c1913d94e6..899b0efc3b9f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -155,12 +155,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback { return mHost.createTile(subPanel); } - protected void createCustomizePanel() { - mCustomizePanel = (QSCustomizer) LayoutInflater.from(mContext) - .inflate(R.layout.qs_customize_panel, null); - mCustomizePanel.setHost(mHost); - } - public void setBrightnessMirror(BrightnessMirrorController c) { super.onFinishInflate(); ToggleSlider brightnessSlider = (ToggleSlider) findViewById(R.id.brightness_slider); @@ -173,12 +167,15 @@ public class QSPanel extends LinearLayout implements Tunable, Callback { mCallback = callback; } - public void setHost(QSTileHost host) { + public void setHost(QSTileHost host, QSCustomizer customizer) { mHost = host; mHost.addCallback(this); setTiles(mHost.getTiles()); mFooter.setHost(host); - createCustomizePanel(); + mCustomizePanel = customizer; + if (mCustomizePanel != null) { + mCustomizePanel.setHost(mHost); + } } public QSTileHost getHost() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java index f8a57d08e5b9..d0e034bc4890 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java @@ -67,11 +67,6 @@ public class QuickQSPanel extends QSPanel { TunerService.get(mContext).removeTunable(mNumTiles); } - @Override - protected void createCustomizePanel() { - // No customizing from the header. - } - public void setQSPanelAndHeader(QSPanel fullPanel, View header) { mFullPanel = fullPanel; mHeader = header; diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java index 5e02428a3dc2..068efa6aaa37 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java @@ -32,8 +32,10 @@ import android.widget.LinearLayout; import android.widget.Toolbar; import android.widget.Toolbar.OnMenuItemClickListener; import com.android.systemui.R; +import com.android.systemui.qs.QSContainer; import com.android.systemui.qs.QSDetailClipper; import com.android.systemui.qs.QSTile; +import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer; import com.android.systemui.statusbar.phone.PhoneStatusBar; import com.android.systemui.statusbar.phone.QSTileHost; @@ -59,6 +61,9 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene private RecyclerView mRecyclerView; private TileAdapter mTileAdapter; private Toolbar mToolbar; + private boolean mCustomizing; + private NotificationsQuickSettingsContainer mNotifQsContainer; + private QSContainer mQsContainer; public QSCustomizer(Context context, AttributeSet attrs) { super(new ContextThemeWrapper(context, android.R.style.Theme_Material), attrs); @@ -70,6 +75,14 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene mPhoneStatusBar = host.getPhoneStatusBar(); } + public void setContainer(NotificationsQuickSettingsContainer notificationsQsContainer) { + mNotifQsContainer = notificationsQsContainer; + } + + public void setQsContainer(QSContainer qsContainer) { + mQsContainer = qsContainer; + } + @Override protected void onFinishInflate() { super.onFinishInflate(); @@ -105,23 +118,31 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene public void show(int x, int y) { if (!isShown) { isShown = true; - mPhoneStatusBar.getStatusBarWindow().addView(this); setTileSpecs(); - mClipper.animateCircularClip(x, y, true, null); + setVisibility(View.VISIBLE); + mClipper.animateCircularClip(x, y, true, mExpandAnimationListener); new TileQueryHelper(mContext, mHost).setListener(mTileAdapter); + mNotifQsContainer.setCustomizerAnimating(true); } } public void hide(int x, int y) { if (isShown) { isShown = false; + setCustomizing(false); save(); mClipper.animateCircularClip(x, y, false, mCollapseAnimationListener); + mNotifQsContainer.setCustomizerAnimating(true); } } + private void setCustomizing(boolean customizing) { + mCustomizing = customizing; + mQsContainer.notifyCustomizeChanged(); + } + public boolean isCustomizing() { - return isShown; + return mCustomizing; } @Override @@ -155,19 +176,34 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene mTileAdapter.saveSpecs(mHost); } + private final AnimatorListener mExpandAnimationListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + setCustomizing(true); + mNotifQsContainer.setCustomizerAnimating(false); + } + + @Override + public void onAnimationCancel(Animator animation) { + mNotifQsContainer.setCustomizerAnimating(false); + } + }; + private final AnimatorListener mCollapseAnimationListener = new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (!isShown) { - mPhoneStatusBar.getStatusBarWindow().removeView(QSCustomizer.this); + setVisibility(View.GONE); } + mNotifQsContainer.setCustomizerAnimating(false); } @Override public void onAnimationCancel(Animator animation) { if (!isShown) { - mPhoneStatusBar.getStatusBarWindow().removeView(QSCustomizer.this); + setVisibility(View.GONE); } + mNotifQsContainer.setCustomizerAnimating(false); } }; } 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 88b8afae3079..9c6f2c53f9e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -65,7 +65,7 @@ import com.android.systemui.statusbar.stack.StackStateAnimator; import java.util.List; public class NotificationPanelView extends PanelView implements - ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener, + ExpandableView.OnHeightChangedListener, View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener, KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener, HeadsUpManager.OnHeadsUpChangedListener { @@ -222,6 +222,7 @@ public class NotificationPanelView extends PanelView implements @Override public void onInflated(View v) { mQsContainer = (QSContainer) v.findViewById(R.id.quick_settings_container); + mQsContainer.setPanelView(NotificationPanelView.this); mQsContainer.getHeader().setOnClickListener(NotificationPanelView.this); } }); @@ -247,7 +248,7 @@ public class NotificationPanelView extends PanelView implements final int height = bottom - top; final int oldHeight = oldBottom - oldTop; if (height != oldHeight) { - onScrollChanged(); + onQsHeightChanged(); } } }); @@ -547,7 +548,7 @@ public class NotificationPanelView extends PanelView implements @Override public boolean onInterceptTouchEvent(MotionEvent event) { - if (mBlockTouches) { + if (mBlockTouches || mQsContainer.isCustomizing()) { return false; } initDownStates(event); @@ -707,7 +708,7 @@ public class NotificationPanelView extends PanelView implements @Override public boolean onTouchEvent(MotionEvent event) { - if (mBlockTouches) { + if (mBlockTouches || mQsContainer.isCustomizing()) { return false; } initDownStates(event); @@ -906,18 +907,6 @@ public class NotificationPanelView extends PanelView implements } @Override - public void onOverscrolled(float lastTouchX, float lastTouchY, int amount) { - if (mIntercepting && shouldQuickSettingsIntercept(lastTouchX, lastTouchY, - -1 /* yDiff: Not relevant here */)) { - mQsTracking = true; - onQsExpansionStarted(amount); - mInitialHeightOnTouch = mQsExpansionHeight; - mInitialTouchY = mLastTouchY; - mInitialTouchX = mLastTouchX; - } - } - - @Override public void onOverscrollTopChanged(float amount, boolean isRubberbanded) { cancelQsAnimation(); if (!mQsExpansionEnabled) { @@ -1719,9 +1708,10 @@ public class NotificationPanelView extends PanelView implements public void onReset(ExpandableView view) { } - @Override - public void onScrollChanged() { + public void onQsHeightChanged() { + mQsMaxExpansionHeight = mQsContainer.getDesiredHeight(); if (mQsExpanded) { + mQsExpansionHeight = mQsMaxExpansionHeight; requestScrollerTopPaddingUpdate(false /* animate */); requestPanelHeightUpdate(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java index 6d90e5cf416f..f0df7068b74c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java @@ -24,21 +24,24 @@ import android.view.View; import android.view.ViewStub; import android.view.WindowInsets; import android.widget.FrameLayout; - +import com.android.systemui.DensityContainer; import com.android.systemui.R; +import com.android.systemui.qs.QSContainer; +import com.android.systemui.qs.customize.QSCustomizer; /** * The container with notification stack scroller and quick settings inside. */ public class NotificationsQuickSettingsContainer extends FrameLayout - implements ViewStub.OnInflateListener { + implements ViewStub.OnInflateListener, DensityContainer.InflateListener { - private View mQsContainer; + private DensityContainer mQsContainer; private View mUserSwitcher; private View mStackScroller; private View mKeyguardStatusBar; private boolean mInflated; private boolean mQsExpanded; + private boolean mCustomizerAnimating; public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) { super(context, attrs); @@ -47,7 +50,8 @@ public class NotificationsQuickSettingsContainer extends FrameLayout @Override protected void onFinishInflate() { super.onFinishInflate(); - mQsContainer = findViewById(R.id.qs_density_container); + mQsContainer = (DensityContainer) findViewById(R.id.qs_density_container); + mQsContainer.addInflateListener(this); mStackScroller = findViewById(R.id.notification_stack_scroller); mKeyguardStatusBar = findViewById(R.id.keyguard_header); ViewStub userSwitcher = (ViewStub) findViewById(R.id.keyguard_user_switcher); @@ -80,8 +84,9 @@ public class NotificationsQuickSettingsContainer extends FrameLayout boolean userSwitcherVisible = mInflated && mUserSwitcher.getVisibility() == View.VISIBLE; boolean statusBarVisible = mKeyguardStatusBar.getVisibility() == View.VISIBLE; - View stackQsTop = mQsExpanded ? mStackScroller : mQsContainer; - View stackQsBottom = !mQsExpanded ? mStackScroller : mQsContainer; + final boolean qsBottom = mQsExpanded && !mCustomizerAnimating; + View stackQsTop = qsBottom ? mStackScroller : mQsContainer; + View stackQsBottom = !qsBottom ? mStackScroller : mQsContainer; // Invert the order of the scroll view and user switcher such that the notifications receive // touches first but the panel gets drawn above. if (child == mQsContainer) { @@ -117,10 +122,23 @@ public class NotificationsQuickSettingsContainer extends FrameLayout } } + @Override + public void onInflated(View v) { + QSCustomizer customizer = ((QSContainer) v).getCustomizer(); + customizer.setContainer(this); + } + public void setQsExpanded(boolean expanded) { if (mQsExpanded != expanded) { mQsExpanded = expanded; invalidate(); } } + + public void setCustomizerAnimating(boolean isAnimating) { + if (mCustomizerAnimating != isAnimating) { + mCustomizerAnimating = isAnimating; + invalidate(); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java index 326ca2b121a0..b29c807b7ad7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java @@ -296,7 +296,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements mHost = host; host.setHeaderView(this); mHeaderQsPanel.setQSPanelAndHeader(mQsPanel, this); - mHeaderQsPanel.setHost(host); + mHeaderQsPanel.setHost(host, null /* No customization in header */); setUserInfoController(host.getUserInfoController()); setBatteryController(host.getBatteryController()); setNextAlarmController(host.getNextAlarmController()); |