Loading packages/SystemUI/res/layout/qs_panel.xml +2 −2 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> <FrameLayout <com.android.systemui.qs.QSContainer xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/quick_settings_container" android:layout_width="match_parent" Loading @@ -28,4 +28,4 @@ android:background="#0000" android:layout_width="match_parent" android:layout_height="wrap_content" /> </FrameLayout> </com.android.systemui.qs.QSContainer> packages/SystemUI/src/com/android/systemui/qs/QSContainer.java 0 → 100644 +76 −0 Original line number Diff line number Diff line /* * 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.qs; import android.content.Context; import android.util.AttributeSet; import android.widget.FrameLayout; import com.android.systemui.R; /** * Wrapper view with background which contains {@link QSPanel} */ public class QSContainer extends FrameLayout { private int mHeightOverride = -1; private QSPanel mQSPanel; public QSContainer(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFinishInflate() { super.onFinishInflate(); mQSPanel = (QSPanel) findViewById(R.id.quick_settings_panel); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); updateBottom(); } /** * 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. * * @param heightOverride the overridden height */ public void setHeightOverride(int heightOverride) { mHeightOverride = heightOverride; updateBottom(); } /** * The height this view wants to be. This is different from {@link #getMeasuredHeight} such that * during closing the detail panel, this already returns the smaller height. */ public int getDesiredHeight() { if (mQSPanel.isClosingDetail()) { return mQSPanel.getGridHeight() + getPaddingTop() + getPaddingBottom(); } else { return getMeasuredHeight(); } } private void updateBottom() { int height = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight(); setBottom(getTop() + height); } } packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +13 −0 Original line number Diff line number Diff line Loading @@ -67,8 +67,10 @@ public class QSPanel extends ViewGroup { private int mPanelPaddingBottom; private int mDualTileUnderlap; private int mBrightnessPaddingTop; private int mGridHeight; private boolean mExpanded; private boolean mListening; private boolean mClosingDetail; private Record mDetailRecord; private Callback mCallback; Loading Loading @@ -320,6 +322,14 @@ public class QSPanel extends ViewGroup { showDetail(false, mDetailRecord); } public boolean isClosingDetail() { return mClosingDetail; } public int getGridHeight() { return mGridHeight; } private void handleShowDetail(Record r, boolean show) { if (r instanceof TileRecord) { handleShowDetailTile((TileRecord) r, show); Loading Loading @@ -364,6 +374,7 @@ public class QSPanel extends ViewGroup { setDetailRecord(r); listener = mHideGridContentWhenDone; } else { mClosingDetail = true; setGridContentVisibility(true); listener = mTeardownDetailWhenDone; fireScanStateChanged(false); Loading Loading @@ -426,6 +437,7 @@ public class QSPanel extends ViewGroup { if (mDetail.getMeasuredHeight() < h) { mDetail.measure(exactly(width), exactly(h)); } mGridHeight = h; setMeasuredDimension(width, Math.max(h, mDetail.getMeasuredHeight())); } Loading Loading @@ -537,6 +549,7 @@ public class QSPanel extends ViewGroup { public void onAnimationEnd(Animator animation) { mDetailContent.removeAllViews(); setDetailRecord(null); mClosingDetail = false; }; }; Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +62 −12 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.widget.TextView; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.R; import com.android.systemui.qs.QSContainer; import com.android.systemui.qs.QSPanel; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.FlingAnimationUtils; Loading Loading @@ -71,7 +72,7 @@ public class NotificationPanelView extends PanelView implements private StatusBarHeaderView mHeader; private KeyguardUserSwitcher mKeyguardUserSwitcher; private KeyguardStatusBarView mKeyguardStatusBar; private View mQsContainer; private QSContainer mQsContainer; private QSPanel mQsPanel; private KeyguardStatusView mKeyguardStatusView; private ObservableScrollView mScrollView; Loading Loading @@ -161,6 +162,7 @@ public class NotificationPanelView extends PanelView implements private boolean mKeyguardStatusViewAnimating; private boolean mHeaderAnimatingIn; private ObjectAnimator mQsContainerAnimator; private ValueAnimator mQsSizeChangeAnimator; private boolean mShadeEmpty; Loading Loading @@ -188,7 +190,7 @@ public class NotificationPanelView extends PanelView implements mHeader.setOnClickListener(this); mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header); mKeyguardStatusView = (KeyguardStatusView) findViewById(R.id.keyguard_status_view); mQsContainer = findViewById(R.id.quick_settings_container); mQsContainer = (QSContainer) findViewById(R.id.quick_settings_container); mQsPanel = (QSPanel) findViewById(R.id.quick_settings_panel); mClockView = (TextView) findViewById(R.id.clock_view); mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view); Loading Loading @@ -283,21 +285,35 @@ public class NotificationPanelView extends PanelView implements mKeyguardStatusView.setPivotY((FONT_HEIGHT - CAP_HEIGHT) / 2048f * mClockView.getTextSize()); // Calculate quick setting heights. int oldMaxHeight = mQsMaxExpansionHeight; mQsMinExpansionHeight = mKeyguardShowing ? 0 : mHeader.getCollapsedHeight() + mQsPeekHeight; mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight(); mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getDesiredHeight(); positionClockAndNotifications(); if (mQsExpanded) { if (mQsFullyExpanded) { if (mQsExpanded && mQsFullyExpanded) { mQsExpansionHeight = mQsMaxExpansionHeight; requestScrollerTopPaddingUpdate(false /* animate */); requestPanelHeightUpdate(); // Size has changed, start an animation. if (mQsMaxExpansionHeight != oldMaxHeight) { startQsSizeChangeAnimation(oldMaxHeight, mQsMaxExpansionHeight); } } else { } else if (!mQsExpanded) { setQsExpansion(mQsMinExpansionHeight + mLastOverscroll); mNotificationStackScroller.setStackHeight(getExpandedHeight()); } mNotificationStackScroller.setStackHeight(getExpandedHeight()); updateHeader(); mNotificationStackScroller.updateIsSmallScreen( mHeader.getCollapsedHeight() + mQsPeekHeight); // If we are running a size change animation, the animation takes care of the height of // the container. However, if we are not animating, we always need to make the QS container // the desired height so when closing the QS detail, it stays smaller after the size change // animation is finished but the detail view is still being animated away (this animation // takes longer than the size change animation). if (mQsSizeChangeAnimator == null) { mQsContainer.setHeightOverride(mQsContainer.getDesiredHeight()); } } @Override Loading @@ -310,6 +326,32 @@ public class NotificationPanelView extends PanelView implements mSecureCameraLaunchManager.destroy(); } private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) { if (mQsSizeChangeAnimator != null) { oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue(); mQsSizeChangeAnimator.cancel(); } mQsSizeChangeAnimator = ValueAnimator.ofInt(oldHeight, newHeight); mQsSizeChangeAnimator.setDuration(300); mQsSizeChangeAnimator.setInterpolator(mFastOutSlowInInterpolator); mQsSizeChangeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { requestScrollerTopPaddingUpdate(false /* animate */); requestPanelHeightUpdate(); int height = (int) mQsSizeChangeAnimator.getAnimatedValue(); mQsContainer.setHeightOverride(height - mHeader.getExpandedHeight()); } }); mQsSizeChangeAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mQsSizeChangeAnimator = null; } }); mQsSizeChangeAnimator.start(); } /** * Positions the clock and notifications dynamically depending on how many notifications are * showing. Loading Loading @@ -1113,7 +1155,7 @@ public class NotificationPanelView extends PanelView implements private void setQsTranslation(float height) { if (!mHeaderAnimatingIn) { mQsContainer.setY(height - mQsContainer.getHeight() + getHeaderTranslation()); mQsContainer.setY(height - mQsContainer.getDesiredHeight() + getHeaderTranslation()); } if (mKeyguardShowing) { mHeader.setY(interpolate(getQsExpansionFraction(), -mHeader.getHeight(), 0)); Loading @@ -1137,6 +1179,8 @@ public class NotificationPanelView extends PanelView implements : maxQs; return (int) interpolate(getExpandedFraction(), mQsMinExpansionHeight, max); } else if (mQsSizeChangeAnimator != null) { return (int) mQsSizeChangeAnimator.getAnimatedValue(); } else if (mKeyguardShowing && mScrollYOverride == -1) { // We can only do the smoother transition on Keyguard when we also are not collapsing Loading Loading @@ -1348,14 +1392,20 @@ public class NotificationPanelView extends PanelView implements + mNotificationStackScroller.getBottomStackPeekSize() + mNotificationStackScroller.getCollapseSecondCardPadding(); } int maxQsHeight = mQsMaxExpansionHeight; // If an animation is changing the size of the QS panel, take the animated value. if (mQsSizeChangeAnimator != null) { maxQsHeight = (int) mQsSizeChangeAnimator.getAnimatedValue(); } float totalHeight = Math.max( mQsMaxExpansionHeight + mNotificationStackScroller.getNotificationTopPadding(), maxQsHeight + mNotificationStackScroller.getNotificationTopPadding(), mStatusBarState == StatusBarState.KEYGUARD ? mClockPositionResult.stackScrollerPadding - mTopPaddingAdjustment : 0) + notificationHeight; if (totalHeight > mNotificationStackScroller.getHeight()) { float fullyCollapsedHeight = mQsMaxExpansionHeight float fullyCollapsedHeight = maxQsHeight + mNotificationStackScroller.getMinStackHeight() + mNotificationStackScroller.getNotificationTopPadding() - getScrollViewScrollY(); Loading Loading
packages/SystemUI/res/layout/qs_panel.xml +2 −2 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> <FrameLayout <com.android.systemui.qs.QSContainer xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/quick_settings_container" android:layout_width="match_parent" Loading @@ -28,4 +28,4 @@ android:background="#0000" android:layout_width="match_parent" android:layout_height="wrap_content" /> </FrameLayout> </com.android.systemui.qs.QSContainer>
packages/SystemUI/src/com/android/systemui/qs/QSContainer.java 0 → 100644 +76 −0 Original line number Diff line number Diff line /* * 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.qs; import android.content.Context; import android.util.AttributeSet; import android.widget.FrameLayout; import com.android.systemui.R; /** * Wrapper view with background which contains {@link QSPanel} */ public class QSContainer extends FrameLayout { private int mHeightOverride = -1; private QSPanel mQSPanel; public QSContainer(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFinishInflate() { super.onFinishInflate(); mQSPanel = (QSPanel) findViewById(R.id.quick_settings_panel); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); updateBottom(); } /** * 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. * * @param heightOverride the overridden height */ public void setHeightOverride(int heightOverride) { mHeightOverride = heightOverride; updateBottom(); } /** * The height this view wants to be. This is different from {@link #getMeasuredHeight} such that * during closing the detail panel, this already returns the smaller height. */ public int getDesiredHeight() { if (mQSPanel.isClosingDetail()) { return mQSPanel.getGridHeight() + getPaddingTop() + getPaddingBottom(); } else { return getMeasuredHeight(); } } private void updateBottom() { int height = mHeightOverride != -1 ? mHeightOverride : getMeasuredHeight(); setBottom(getTop() + height); } }
packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +13 −0 Original line number Diff line number Diff line Loading @@ -67,8 +67,10 @@ public class QSPanel extends ViewGroup { private int mPanelPaddingBottom; private int mDualTileUnderlap; private int mBrightnessPaddingTop; private int mGridHeight; private boolean mExpanded; private boolean mListening; private boolean mClosingDetail; private Record mDetailRecord; private Callback mCallback; Loading Loading @@ -320,6 +322,14 @@ public class QSPanel extends ViewGroup { showDetail(false, mDetailRecord); } public boolean isClosingDetail() { return mClosingDetail; } public int getGridHeight() { return mGridHeight; } private void handleShowDetail(Record r, boolean show) { if (r instanceof TileRecord) { handleShowDetailTile((TileRecord) r, show); Loading Loading @@ -364,6 +374,7 @@ public class QSPanel extends ViewGroup { setDetailRecord(r); listener = mHideGridContentWhenDone; } else { mClosingDetail = true; setGridContentVisibility(true); listener = mTeardownDetailWhenDone; fireScanStateChanged(false); Loading Loading @@ -426,6 +437,7 @@ public class QSPanel extends ViewGroup { if (mDetail.getMeasuredHeight() < h) { mDetail.measure(exactly(width), exactly(h)); } mGridHeight = h; setMeasuredDimension(width, Math.max(h, mDetail.getMeasuredHeight())); } Loading Loading @@ -537,6 +549,7 @@ public class QSPanel extends ViewGroup { public void onAnimationEnd(Animator animation) { mDetailContent.removeAllViews(); setDetailRecord(null); mClosingDetail = false; }; }; Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +62 −12 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import android.widget.TextView; import com.android.keyguard.KeyguardStatusView; import com.android.systemui.R; import com.android.systemui.qs.QSContainer; import com.android.systemui.qs.QSPanel; import com.android.systemui.statusbar.ExpandableView; import com.android.systemui.statusbar.FlingAnimationUtils; Loading Loading @@ -71,7 +72,7 @@ public class NotificationPanelView extends PanelView implements private StatusBarHeaderView mHeader; private KeyguardUserSwitcher mKeyguardUserSwitcher; private KeyguardStatusBarView mKeyguardStatusBar; private View mQsContainer; private QSContainer mQsContainer; private QSPanel mQsPanel; private KeyguardStatusView mKeyguardStatusView; private ObservableScrollView mScrollView; Loading Loading @@ -161,6 +162,7 @@ public class NotificationPanelView extends PanelView implements private boolean mKeyguardStatusViewAnimating; private boolean mHeaderAnimatingIn; private ObjectAnimator mQsContainerAnimator; private ValueAnimator mQsSizeChangeAnimator; private boolean mShadeEmpty; Loading Loading @@ -188,7 +190,7 @@ public class NotificationPanelView extends PanelView implements mHeader.setOnClickListener(this); mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header); mKeyguardStatusView = (KeyguardStatusView) findViewById(R.id.keyguard_status_view); mQsContainer = findViewById(R.id.quick_settings_container); mQsContainer = (QSContainer) findViewById(R.id.quick_settings_container); mQsPanel = (QSPanel) findViewById(R.id.quick_settings_panel); mClockView = (TextView) findViewById(R.id.clock_view); mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view); Loading Loading @@ -283,21 +285,35 @@ public class NotificationPanelView extends PanelView implements mKeyguardStatusView.setPivotY((FONT_HEIGHT - CAP_HEIGHT) / 2048f * mClockView.getTextSize()); // Calculate quick setting heights. int oldMaxHeight = mQsMaxExpansionHeight; mQsMinExpansionHeight = mKeyguardShowing ? 0 : mHeader.getCollapsedHeight() + mQsPeekHeight; mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight(); mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getDesiredHeight(); positionClockAndNotifications(); if (mQsExpanded) { if (mQsFullyExpanded) { if (mQsExpanded && mQsFullyExpanded) { mQsExpansionHeight = mQsMaxExpansionHeight; requestScrollerTopPaddingUpdate(false /* animate */); requestPanelHeightUpdate(); // Size has changed, start an animation. if (mQsMaxExpansionHeight != oldMaxHeight) { startQsSizeChangeAnimation(oldMaxHeight, mQsMaxExpansionHeight); } } else { } else if (!mQsExpanded) { setQsExpansion(mQsMinExpansionHeight + mLastOverscroll); mNotificationStackScroller.setStackHeight(getExpandedHeight()); } mNotificationStackScroller.setStackHeight(getExpandedHeight()); updateHeader(); mNotificationStackScroller.updateIsSmallScreen( mHeader.getCollapsedHeight() + mQsPeekHeight); // If we are running a size change animation, the animation takes care of the height of // the container. However, if we are not animating, we always need to make the QS container // the desired height so when closing the QS detail, it stays smaller after the size change // animation is finished but the detail view is still being animated away (this animation // takes longer than the size change animation). if (mQsSizeChangeAnimator == null) { mQsContainer.setHeightOverride(mQsContainer.getDesiredHeight()); } } @Override Loading @@ -310,6 +326,32 @@ public class NotificationPanelView extends PanelView implements mSecureCameraLaunchManager.destroy(); } private void startQsSizeChangeAnimation(int oldHeight, final int newHeight) { if (mQsSizeChangeAnimator != null) { oldHeight = (int) mQsSizeChangeAnimator.getAnimatedValue(); mQsSizeChangeAnimator.cancel(); } mQsSizeChangeAnimator = ValueAnimator.ofInt(oldHeight, newHeight); mQsSizeChangeAnimator.setDuration(300); mQsSizeChangeAnimator.setInterpolator(mFastOutSlowInInterpolator); mQsSizeChangeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { requestScrollerTopPaddingUpdate(false /* animate */); requestPanelHeightUpdate(); int height = (int) mQsSizeChangeAnimator.getAnimatedValue(); mQsContainer.setHeightOverride(height - mHeader.getExpandedHeight()); } }); mQsSizeChangeAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mQsSizeChangeAnimator = null; } }); mQsSizeChangeAnimator.start(); } /** * Positions the clock and notifications dynamically depending on how many notifications are * showing. Loading Loading @@ -1113,7 +1155,7 @@ public class NotificationPanelView extends PanelView implements private void setQsTranslation(float height) { if (!mHeaderAnimatingIn) { mQsContainer.setY(height - mQsContainer.getHeight() + getHeaderTranslation()); mQsContainer.setY(height - mQsContainer.getDesiredHeight() + getHeaderTranslation()); } if (mKeyguardShowing) { mHeader.setY(interpolate(getQsExpansionFraction(), -mHeader.getHeight(), 0)); Loading @@ -1137,6 +1179,8 @@ public class NotificationPanelView extends PanelView implements : maxQs; return (int) interpolate(getExpandedFraction(), mQsMinExpansionHeight, max); } else if (mQsSizeChangeAnimator != null) { return (int) mQsSizeChangeAnimator.getAnimatedValue(); } else if (mKeyguardShowing && mScrollYOverride == -1) { // We can only do the smoother transition on Keyguard when we also are not collapsing Loading Loading @@ -1348,14 +1392,20 @@ public class NotificationPanelView extends PanelView implements + mNotificationStackScroller.getBottomStackPeekSize() + mNotificationStackScroller.getCollapseSecondCardPadding(); } int maxQsHeight = mQsMaxExpansionHeight; // If an animation is changing the size of the QS panel, take the animated value. if (mQsSizeChangeAnimator != null) { maxQsHeight = (int) mQsSizeChangeAnimator.getAnimatedValue(); } float totalHeight = Math.max( mQsMaxExpansionHeight + mNotificationStackScroller.getNotificationTopPadding(), maxQsHeight + mNotificationStackScroller.getNotificationTopPadding(), mStatusBarState == StatusBarState.KEYGUARD ? mClockPositionResult.stackScrollerPadding - mTopPaddingAdjustment : 0) + notificationHeight; if (totalHeight > mNotificationStackScroller.getHeight()) { float fullyCollapsedHeight = mQsMaxExpansionHeight float fullyCollapsedHeight = maxQsHeight + mNotificationStackScroller.getMinStackHeight() + mNotificationStackScroller.getNotificationTopPadding() - getScrollViewScrollY(); Loading