android:id="@+id/keyguard_status_view"
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
androidprv:layout_maxWidth="@dimen/keyguard_security_width"
androidprv:layout_maxHeight="@dimen/keyguard_security_height"
android:gravity="center_horizontal|top"
<!-- Keyguard dimensions -->
<!-- Size of the clock font in keyguard's status view -->
- <dimen name="kg_status_clock_font_size">141dp</dimen>
+ <dimen name="kg_status_clock_font_size">120dp</dimen>
<!-- Size of the generic status lines keyguard's status view -->
<dimen name="kg_status_line_font_size">16sp</dimen>
<resources>
<!-- Keyguard dimensions -->
<!-- Size of the clock font in keyguard's status view -->
- <dimen name="kg_status_clock_font_size">188dp</dimen>
+ <dimen name="kg_status_clock_font_size">140dp</dimen>
<!-- Size of the generic status lines keyguard's status view -->
<dimen name="kg_status_line_font_size">19sp</dimen>
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium" />
- <LinearLayout
+ <include layout="@layout/status_bar_expanded_header"
android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_panel_header_height"
+ />
+
+ <include
+ layout="@layout/keyguard_status_view"
android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/close_handle_underlap"
- android:orientation="vertical"
- android:animateLayoutChanges="false"
- >
+ android:visibility="gone" />
- <include layout="@layout/status_bar_expanded_header"
- android:layout_width="match_parent"
- android:layout_height="@dimen/notification_panel_header_height"
- />
+ <TextView
+ android:id="@+id/emergency_calls_only"
+ android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network.EmergencyOnly"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:padding="4dp"
+ android:gravity="center"
+ android:visibility="gone"
+ />
+ <FrameLayout
+ android:id="@+id/notification_container_parent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/close_handle_underlap"
+ >
<include
- layout="@layout/keyguard_status_view"
- android:visibility="gone" />
-
- <TextView
- android:id="@+id/emergency_calls_only"
- android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network.EmergencyOnly"
- android:layout_height="wrap_content"
+ layout="@layout/flip_settings"
+ android:layout_marginTop="@dimen/notification_panel_header_height"
android:layout_width="match_parent"
- android:padding="4dp"
- android:gravity="center"
- android:visibility="gone"
+ android:layout_height="wrap_content"
/>
- <FrameLayout
- android:id="@+id/notification_container_parent"
+ <com.android.systemui.statusbar.stack.NotificationStackScrollLayout
+ android:id="@+id/notification_stack_scroller"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- >
- <include
- layout="@layout/flip_settings"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- />
-
- <com.android.systemui.statusbar.stack.NotificationStackScrollLayout
- android:id="@+id/notification_stack_scroller"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- />
- </FrameLayout>
- </LinearLayout>
+ />
+ </FrameLayout>
<include
layout="@layout/keyguard_bottom_area"
<dimen name="quick_settings_tmp_scrim_stroke_width">8dp</dimen>
<dimen name="quick_settings_tmp_scrim_text_size">30dp</dimen>
+
+ <dimen name="notifications_top_padding">8dp</dimen>
</resources>
private View mKeyguardStatusView;
private NotificationStackScrollLayout mNotificationStackScroller;
- private int[] mTempLocation = new int[2];
- private int[] mTempChildLocation = new int[2];
- private View mNotificationParent;
private boolean mTrackingSettings;
- private float mExpandedHeight = -1;
+ private int mNotificationTopPadding;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
mNotificationStackScroller = (NotificationStackScrollLayout)
findViewById(R.id.notification_stack_scroller);
mNotificationStackScroller.setOnHeightChangedListener(this);
- mNotificationParent = findViewById(R.id.notification_container_parent);
+ mNotificationTopPadding = getResources().getDimensionPixelSize(
+ R.dimen.notifications_top_padding);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ int keyguardBottomMargin =
+ ((MarginLayoutParams) mKeyguardStatusView.getLayoutParams()).bottomMargin;
+ mNotificationStackScroller.setTopPadding(mStatusBar.isOnKeyguard()
+ ? mKeyguardStatusView.getBottom() + keyguardBottomMargin
+ : mHeader.getBottom() + mNotificationTopPadding);
}
@Override
return super.dispatchPopulateAccessibilityEvent(event);
}
- /**
- * Gets the relative position of a view on the screen in regard to this view.
- *
- * @param requestedView the view we want to find the relative position for
- * @return
- */
- private int getRelativeTop(View requestedView) {
- getLocationOnScreen(mTempLocation);
- requestedView.getLocationOnScreen(mTempChildLocation);
- return mTempChildLocation[1] - mTempLocation[1];
- }
-
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// intercept for quick settings
@Override
protected void onHeightUpdated(float expandedHeight) {
- updateNotificationStackHeight(expandedHeight);
- }
-
- /**
- * Update the height of the {@link #mNotificationStackScroller} to the new expanded height.
- * This is much more efficient than doing it over the layout pass.
- *
- * @param expandedHeight the new expanded height
- */
- private void updateNotificationStackHeight(float expandedHeight) {
- if (mExpandedHeight == expandedHeight) return;
- mExpandedHeight = expandedHeight;
- mNotificationStackScroller.setIsExpanded(expandedHeight > 0.0f);
- float childOffset = getRelativeTop(mNotificationStackScroller)
- - mNotificationParent.getTranslationY();
- int newStackHeight = (int) (expandedHeight - childOffset);
- int itemHeight = mNotificationStackScroller.getItemHeight();
- int bottomStackPeekSize = mNotificationStackScroller.getBottomStackPeekSize();
- int minStackHeight = itemHeight + bottomStackPeekSize;
- if (newStackHeight >= minStackHeight) {
- mNotificationParent.setTranslationY(0);
- mNotificationStackScroller.setCurrentStackHeight(newStackHeight);
- } else {
-
- // We did not reach the position yet where we actually start growing,
- // so we translate the stack upwards.
- int translationY = (newStackHeight - minStackHeight);
- // A slight parallax effect is introduced in order for the stack to catch up with
- // the top card.
- float partiallyThere = (float) newStackHeight / minStackHeight;
- partiallyThere = Math.max(0, partiallyThere);
- translationY += (1 - partiallyThere) * bottomStackPeekSize;
- mNotificationParent.setTranslationY(translationY);
- mNotificationStackScroller.setCurrentStackHeight(
- (int) (expandedHeight - (childOffset + translationY)));
- }
+ mNotificationStackScroller.setStackHeight(expandedHeight);
}
@Override
private int mBottomStackPeekSize;
private int mEmptyMarginBottom;
private int mPaddingBetweenElements;
+ private int mTopPadding;
private boolean mListenForHeightChanges = true;
/**
private void setMaxLayoutHeight(int maxLayoutHeight) {
mMaxLayoutHeight = maxLayoutHeight;
- updateAlgorithmHeight();
+ updateAlgorithmHeightAndPadding();
}
- private void updateAlgorithmHeight() {
+ private void updateAlgorithmHeightAndPadding() {
mStackScrollAlgorithm.setLayoutHeight(getLayoutHeight());
+ mStackScrollAlgorithm.setTopPadding(mTopPadding);
}
/**
}
}
- public void setCurrentStackHeight(int currentStackHeight) {
- this.mCurrentStackHeight = currentStackHeight;
- updateAlgorithmHeight();
- updateChildren();
+ public int getTopPadding() {
+ return mTopPadding;
+ }
+
+ public void setTopPadding(int topPadding) {
+ if (mTopPadding != topPadding) {
+ mTopPadding = topPadding;
+ updateAlgorithmHeightAndPadding();
+ updateContentHeight();
+ updateChildren();
+ }
+ }
+
+ /**
+ * Update the height of the stack to a new height.
+ *
+ * @param height the new height of the stack
+ */
+ public void setStackHeight(float height) {
+ setIsExpanded(height > 0.0f);
+ int newStackHeight = (int) height;
+ int itemHeight = getItemHeight();
+ int bottomStackPeekSize = mBottomStackPeekSize;
+ int minStackHeight = itemHeight + bottomStackPeekSize;
+ int stackHeight;
+ if (newStackHeight - mTopPadding >= minStackHeight) {
+ setTranslationY(0);
+ stackHeight = newStackHeight;
+ } else {
+
+ // We did not reach the position yet where we actually start growing,
+ // so we translate the stack upwards.
+ int translationY = (newStackHeight - minStackHeight);
+ // A slight parallax effect is introduced in order for the stack to catch up with
+ // the top card.
+ float partiallyThere = (float) (newStackHeight - mTopPadding) / minStackHeight;
+ partiallyThere = Math.max(0, partiallyThere);
+ translationY += (1 - partiallyThere) * bottomStackPeekSize;
+ setTranslationY(translationY - mTopPadding);
+ stackHeight = (int) (height - (translationY - mTopPadding));
+ }
+ if (stackHeight != mCurrentStackHeight) {
+ mCurrentStackHeight = stackHeight;
+ updateAlgorithmHeightAndPadding();
+ updateChildren();
+ }
}
/**
}
}
}
- mContentHeight = height;
+ mContentHeight = height + mTopPadding;
}
/**
mStackScrollAlgorithm.onExpansionStopped();
}
- public void setIsExpanded(boolean isExpanded) {
+ private void setIsExpanded(boolean isExpanded) {
mIsExpanded = isExpanded;
mStackScrollAlgorithm.setIsExpanded(isExpanded);
if (!isExpanded) {
private StackIndentationFunctor mBottomStackIndentationFunctor;
private int mLayoutHeight;
+
+ /** mLayoutHeight - mTopPadding */
+ private int mInnerHeight;
+ private int mTopPadding;
private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
private boolean mIsExpansionChanging;
private int mFirstChildMaxHeight;
StackScrollAlgorithmState algorithmState) {
// The starting position of the bottom stack peek
- float bottomPeekStart = mLayoutHeight - mBottomStackPeekSize;
+ float bottomPeekStart = mInnerHeight - mBottomStackPeekSize;
// The position where the bottom stack starts.
float bottomStackStart = bottomPeekStart - mCollapsedSize;
}
currentYPosition = childViewState.yTranslation + childHeight + mPaddingBetweenElements;
yPositionInScrollView = yPositionInScrollViewAfterElement;
+
+ childViewState.yTranslation += mTopPadding;
}
}
private void clampPositionToBottomStackStart(StackScrollState.ViewState childViewState,
int childHeight) {
childViewState.yTranslation = Math.min(childViewState.yTranslation,
- mLayoutHeight - mBottomStackPeekSize - childHeight);
+ mInnerHeight - mBottomStackPeekSize - childHeight);
}
/**
childViewState.alpha = 1.0f - algorithmState.partialInBottom;
}
childViewState.location = StackScrollState.ViewState.LOCATION_BOTTOM_STACK_HIDDEN;
- currentYPosition = mLayoutHeight;
+ currentYPosition = mInnerHeight;
}
childViewState.yTranslation = currentYPosition - childHeight;
clampPositionToTopStackEnd(childViewState, childHeight);
if (i == 0 && algorithmState.scrollY == mCollapsedSize) {
// The starting position of the bottom stack peek
- int bottomPeekStart = mLayoutHeight - mBottomStackPeekSize;
+ int bottomPeekStart = mInnerHeight - mBottomStackPeekSize;
// Collapse and expand the first child while the shade is being expanded
float maxHeight = mIsExpansionChanging && child == mFirstChildWhileExpanding
? mFirstChildMaxHeight
}
}
- public int getLayoutHeight() {
- return mLayoutHeight;
- }
-
public void setLayoutHeight(int layoutHeight) {
this.mLayoutHeight = layoutHeight;
+ updateInnerHeight();
+ }
+
+ public void setTopPadding(int topPadding) {
+ mTopPadding = topPadding;
+ updateInnerHeight();
+ }
+
+ private void updateInnerHeight() {
+ mInnerHeight = mLayoutHeight - mTopPadding;
}
public void onExpansionStarted(StackScrollState currentState) {