Merge "Improve transition when going to Wifi/BT detail panel" into lmp-mr1-dev

This commit is contained in:
Jorim Jaggi
2014-12-12 15:32:16 +00:00
committed by Android (Google) Code Review
4 changed files with 153 additions and 14 deletions

View File

@@ -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"
@@ -28,4 +28,4 @@
android:background="#0000"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
</com.android.systemui.qs.QSContainer>

View File

@@ -0,0 +1,76 @@
/*
* 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);
}
}

View File

@@ -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;
@@ -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);
@@ -364,6 +374,7 @@ public class QSPanel extends ViewGroup {
setDetailRecord(r);
listener = mHideGridContentWhenDone;
} else {
mClosingDetail = true;
setGridContentVisibility(true);
listener = mTeardownDetailWhenDone;
fireScanStateChanged(false);
@@ -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()));
}
@@ -537,6 +549,7 @@ public class QSPanel extends ViewGroup {
public void onAnimationEnd(Animator animation) {
mDetailContent.removeAllViews();
setDetailRecord(null);
mClosingDetail = false;
};
};

View File

@@ -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;
@@ -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;
@@ -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;
@@ -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);
@@ -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) {
mQsExpansionHeight = mQsMaxExpansionHeight;
requestScrollerTopPaddingUpdate(false /* animate */);
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
@@ -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.
@@ -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));
@@ -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
@@ -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();