Updated the paddings of quick settings to match notifications

Now all content is nicely aligned on the same line like the
notifications. Previously this was a mix of statusbar alignment
and some other alignment, that sometimes worked out to actually
be at the same location. The setting of these paddings
is now streamlined in code.
This also ensures that the buttons themselves now nicely align
on the left side of the view instead of being 1dp off.
This also fixes a bug where the paddings were off due to the
last media refactorings on Pixel 2 or non-rounded displays.

Fixes: 156452277
Bug: 157258041
Test: test layout of Qs with and without media notification, with various cutouts.
Change-Id: Id547f9a99577886522e41bdb7e3aedac47db9a9e
This commit is contained in:
Selim Cinek
2020-05-29 20:28:22 -07:00
parent ed48c8aa12
commit 35484aed51
12 changed files with 179 additions and 99 deletions

View File

@@ -21,8 +21,6 @@
android:layout_height="wrap_content"
android:paddingTop="@dimen/qs_header_top_padding"
android:paddingBottom="@dimen/qs_header_bottom_padding"
android:paddingStart="@dimen/status_bar_padding_start"
android:paddingEnd="@dimen/status_bar_padding_end"
android:layout_below="@id/quick_status_bar_system_icons"
android:clipChildren="false"
android:clipToPadding="false"

View File

@@ -18,8 +18,6 @@
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
style="@style/BrightnessDialogContainer">
<com.android.systemui.settings.ToggleSliderView

View File

@@ -19,8 +19,6 @@
android:layout_width="match_parent"
android:layout_height="@dimen/qs_header_tooltip_height"
android:layout_below="@id/quick_status_bar_system_icons"
android:paddingStart="@dimen/status_bar_padding_start"
android:paddingEnd="@dimen/status_bar_padding_end"
android:visibility="invisible"
android:theme="@style/QSHeaderTheme">

View File

@@ -33,6 +33,7 @@
android:paddingStart="0dp"
android:elevation="4dp" >
<!-- The clock -->
<include layout="@layout/quick_status_bar_header_system_icons" />
<!-- Status icons within the panel itself (and not in the top-most status bar) -->

View File

@@ -25,8 +25,6 @@
android:gravity="center"
android:orientation="horizontal"
android:clickable="true"
android:paddingStart="@dimen/status_bar_padding_start"
android:paddingEnd="@dimen/status_bar_padding_end"
android:paddingTop="@dimen/status_bar_padding_top" >
<com.android.systemui.statusbar.policy.Clock

View File

@@ -17,5 +17,4 @@
-->
<resources>
<dimen name="nav_content_padding">8dp</dimen>
<dimen name="qs_header_tile_margin_horizontal">13dp</dimen>
</resources>

View File

@@ -482,7 +482,8 @@
<dimen name="pull_span_min">25dp</dimen>
<dimen name="qs_tile_height">106dp</dimen>
<dimen name="qs_tile_layout_margin_side">6dp</dimen>
<!--notification_side_paddings + notification_content_margin_start - (qs_quick_tile_size - qs_tile_background_size) / 2 -->
<dimen name="qs_tile_layout_margin_side">18dp</dimen>
<dimen name="qs_tile_margin_horizontal">18dp</dimen>
<dimen name="qs_tile_margin_horizontal_two_line">2dp</dimen>
<dimen name="qs_tile_margin_vertical">24dp</dimen>
@@ -498,7 +499,6 @@
<dimen name="qs_quick_tile_size">48dp</dimen>
<dimen name="qs_quick_tile_padding">12dp</dimen>
<dimen name="qs_header_gear_translation">16dp</dimen>
<dimen name="qs_header_tile_margin_horizontal">4dp</dimen>
<dimen name="qs_header_tile_margin_bottom">18dp</dimen>
<dimen name="qs_page_indicator_width">16dp</dimen>
<dimen name="qs_page_indicator_height">8dp</dimen>
@@ -1055,9 +1055,8 @@
<dimen name="edge_margin">8dp</dimen>
<!-- The absolute side margins of quick settings -->
<dimen name="quick_settings_side_margins">16dp</dimen>
<dimen name="quick_settings_expanded_bottom_margin">16dp</dimen>
<dimen name="quick_settings_media_extra_bottom_margin">4dp</dimen>
<dimen name="quick_settings_media_extra_bottom_margin">6dp</dimen>
<dimen name="rounded_corner_content_padding">0dp</dimen>
<dimen name="nav_content_padding">0dp</dimen>
<dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen>

View File

@@ -50,6 +50,8 @@ public class QSContainerImpl extends FrameLayout {
private int mSideMargins;
private boolean mQsDisabled;
private int mContentPaddingStart = -1;
private int mContentPaddingEnd = -1;
public QSContainerImpl(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -66,10 +68,9 @@ public class QSContainerImpl extends FrameLayout {
mBackground = findViewById(R.id.quick_settings_background);
mStatusBarBackground = findViewById(R.id.quick_settings_status_bar_background);
mBackgroundGradient = findViewById(R.id.quick_settings_gradient_view);
mSideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
updateResources();
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
setMargins();
}
@Override
@@ -103,10 +104,15 @@ public class QSContainerImpl extends FrameLayout {
if (navBelow) {
maxQs -= getResources().getDimensionPixelSize(R.dimen.navigation_bar_height);
}
int padding = mPaddingLeft + mPaddingRight + layoutParams.leftMargin
+ layoutParams.rightMargin;
final int qsPanelWidthSpec = getChildMeasureSpec(widthMeasureSpec, padding,
layoutParams.width);
// Measure with EXACTLY. That way, PagedTileLayout will only use excess height and will be
// measured last, after other views and padding is accounted for.
mQSPanel.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maxQs, MeasureSpec.EXACTLY));
int width = mQSPanel.getMeasuredWidth();
mQSPanel.measure(qsPanelWidthSpec, MeasureSpec.makeMeasureSpec(maxQs, MeasureSpec.EXACTLY));
int width = mQSPanel.getMeasuredWidth() + padding;
int height = layoutParams.topMargin + layoutParams.bottomMargin
+ mQSPanel.getMeasuredHeight() + getPaddingBottom();
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
@@ -148,8 +154,18 @@ public class QSContainerImpl extends FrameLayout {
LayoutParams layoutParams = (LayoutParams) mQSPanel.getLayoutParams();
layoutParams.topMargin = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.quick_qs_offset_height);
mQSPanel.setLayoutParams(layoutParams);
mSideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
mContentPaddingStart = getResources().getDimensionPixelSize(
com.android.internal.R.dimen.notification_content_margin_start);
int newPaddingEnd = getResources().getDimensionPixelSize(
com.android.internal.R.dimen.notification_content_margin_end);
boolean marginsChanged = newPaddingEnd != mContentPaddingEnd;
mContentPaddingEnd = newPaddingEnd;
if (marginsChanged) {
updatePaddingsAndMargins();
}
}
/**
@@ -196,17 +212,32 @@ public class QSContainerImpl extends FrameLayout {
updateExpansion();
}
private void setMargins() {
setMargins(mQSDetail);
setMargins(mBackground);
mQSPanel.setMargins(mSideMargins);
mHeader.setMargins(mSideMargins);
}
private void setMargins(View view) {
FrameLayout.LayoutParams lp = (LayoutParams) view.getLayoutParams();
lp.rightMargin = mSideMargins;
lp.leftMargin = mSideMargins;
private void updatePaddingsAndMargins() {
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
if (view == mStatusBarBackground || view == mBackgroundGradient
|| view == mQSCustomizer) {
// Some views are always full width
continue;
}
LayoutParams lp = (LayoutParams) view.getLayoutParams();
lp.rightMargin = mSideMargins;
lp.leftMargin = mSideMargins;
if (view == mQSPanel) {
// QS panel lays out some of its content full width
mQSPanel.setContentMargins(mContentPaddingStart, mContentPaddingEnd);
} else if (view == mHeader) {
// The header contains the QQS panel which needs to have special padding, to
// visually align them.
mHeader.setContentMargins(mContentPaddingStart, mContentPaddingEnd);
} else {
view.setPaddingRelative(
mContentPaddingStart,
view.getPaddingTop(),
mContentPaddingEnd,
view.getPaddingBottom());
}
}
}
private int getDisplayHeight() {

View File

@@ -97,6 +97,8 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
private final H mHandler = new H();
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
private final QSTileRevealController mQsTileRevealController;
/** Whether or not the QS media player feature is enabled. */
protected boolean mUsingMediaPlayer;
protected boolean mExpanded;
protected boolean mListening;
@@ -111,6 +113,9 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
protected QSSecurityFooter mFooter;
private PageIndicator mFooterPageIndicator;
private boolean mGridContentVisible = true;
private int mContentMarginStart;
private int mContentMarginEnd;
private int mVisualTilePadding;
protected QSTileLayout mTileLayout;
@@ -144,6 +149,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
UiEventLogger uiEventLogger
) {
super(context, attrs);
mUsingMediaPlayer = useQsMediaPlayer(context);
mMediaHost = mediaHost;
mContext = context;
mQSLogger = qsLogger;
@@ -192,8 +198,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mMediaHost.init(MediaHierarchyManager.LOCATION_QS);
ViewGroup hostView = mMediaHost.getHostView();
addView(hostView);
int sidePaddings = getResources().getDimensionPixelSize(
R.dimen.quick_settings_side_margins);
int bottomPadding = getResources().getDimensionPixelSize(
R.dimen.quick_settings_expanded_bottom_margin);
MarginLayoutParams layoutParams = (MarginLayoutParams) hostView.getLayoutParams();
@@ -201,8 +205,7 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.bottomMargin = bottomPadding;
hostView.setLayoutParams(layoutParams);
hostView.setPadding(sidePaddings, hostView.getPaddingTop(), sidePaddings,
hostView.getPaddingBottom());
updateMediaHostContentMargins();
}
private final QSMediaBrowser.Callback mMediaBrowserCallback = new QSMediaBrowser.Callback() {
@@ -476,8 +479,10 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
public void updateResources() {
final Resources res = mContext.getResources();
setPadding(0, res.getDimensionPixelSize(R.dimen.qs_panel_padding_top), 0, res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom));
int tileSize = getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
int tileBg = getResources().getDimensionPixelSize(R.dimen.qs_tile_background_size);
mVisualTilePadding = (int) ((tileSize - tileBg) / 2.0f);
updatePadding();
updatePageIndicator();
@@ -489,6 +494,14 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
}
}
protected void updatePadding() {
final Resources res = mContext.getResources();
setPaddingRelative(getPaddingStart(),
res.getDimensionPixelSize(R.dimen.qs_panel_padding_top),
getPaddingEnd(),
res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom));
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@@ -840,17 +853,51 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
mFooter.showDeviceMonitoringDialog();
}
public void setMargins(int sideMargins) {
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
if (view != mTileLayout) {
LayoutParams lp = (LayoutParams) view.getLayoutParams();
lp.leftMargin = sideMargins;
lp.rightMargin = sideMargins;
}
public void setContentMargins(int startMargin, int endMargin) {
// Only some views actually want this content padding, others want to go all the way
// to the edge like the brightness slider
mContentMarginStart = startMargin;
mContentMarginEnd = endMargin;
updateTileLayoutMargins(mContentMarginStart - mVisualTilePadding,
mContentMarginEnd - mVisualTilePadding);
updateMediaHostContentMargins();
}
/**
* Update the margins of all tile Layouts.
*
* @param visualMarginStart the visual start margin of the tile, adjusted for local insets
* to the tile. This can be set on a tileLayout
* @param visualMarginEnd the visual end margin of the tile, adjusted for local insets
* to the tile. This can be set on a tileLayout
*/
protected void updateTileLayoutMargins(int visualMarginStart, int visualMarginEnd) {
updateMargins((View) mTileLayout, visualMarginStart, visualMarginEnd);
}
/**
* Update the margins of the media hosts
*/
protected void updateMediaHostContentMargins() {
if (mUsingMediaPlayer && mMediaHost != null) {
updateMargins(mMediaHost.getHostView(), mContentMarginStart, mContentMarginEnd);
}
}
/**
* Update the margins of a view.
*
* @param view the view to adjust
* @param start the start margin to set
* @param end the end margin to set
*/
protected void updateMargins(View view, int start, int end) {
LayoutParams lp = (LayoutParams) view.getLayoutParams();
lp.setMarginStart(start);
lp.setMarginEnd(end);
view.setLayoutParams(lp);
}
public MediaHost getMediaHost() {
return mMediaHost;
}

View File

@@ -62,8 +62,6 @@ public class QuickQSPanel extends QSPanel {
private boolean mDisabledByPolicy;
private int mMaxTiles;
protected QSPanel mFullPanel;
/** Whether or not the QS media player feature is enabled. */
private boolean mUsingMediaPlayer;
/** Whether or not the QuickQSPanel currently contains a media player. */
private boolean mShowHorizontalTileLayout;
private LinearLayout mHorizontalLinearLayout;
@@ -97,8 +95,6 @@ public class QuickQSPanel extends QSPanel {
}
mMediaBottomMargin = getResources().getDimensionPixelSize(
R.dimen.quick_settings_media_extra_bottom_margin);
mUsingMediaPlayer = Utils.useQsMediaPlayer(context);
if (mUsingMediaPlayer) {
mHorizontalLinearLayout = new LinearLayout(mContext);
mHorizontalLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
@@ -132,7 +128,6 @@ public class QuickQSPanel extends QSPanel {
mHorizontalLinearLayout.setVisibility(useHorizontal ? View.VISIBLE : View.GONE);
addView((View) mRegularTileLayout, 0);
super.setPadding(0, 0, 0, 0);
applySideMargins(mHorizontalLinearLayout);
applyBottomMargin((View) mRegularTileLayout);
} else {
sDefaultMaxTiles = getResources().getInteger(R.integer.quick_qs_panel_max_columns);
@@ -151,14 +146,6 @@ public class QuickQSPanel extends QSPanel {
view.setLayoutParams(layoutParams);
}
private void applySideMargins(View view) {
int margin = getResources().getDimensionPixelSize(R.dimen.qs_header_tile_margin_horizontal);
MarginLayoutParams layoutParams = (MarginLayoutParams) view.getLayoutParams();
layoutParams.setMarginStart(margin);
layoutParams.setMarginEnd(margin);
view.setLayoutParams(layoutParams);
}
private void reAttachMediaHost() {
if (mMediaHost == null) {
return;
@@ -177,10 +164,6 @@ public class QuickQSPanel extends QSPanel {
layoutParams.width = horizontal ? 0 : ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.weight = horizontal ? 1.5f : 0;
layoutParams.bottomMargin = mMediaBottomMargin;
int marginStart = horizontal
? getResources().getDimensionPixelSize(R.dimen.qs_header_tile_margin_horizontal)
: 0;
layoutParams.setMarginStart(marginStart);
}
}
@@ -194,11 +177,22 @@ public class QuickQSPanel extends QSPanel {
mMediaHost.setShowsOnlyActiveMedia(true);
mMediaHost.init(MediaHierarchyManager.LOCATION_QQS);
reAttachMediaHost();
updateMediaHostContentMargins();
}
@Override
public void setPadding(int left, int top, int right, int bottom) {
// Always have no padding.
protected void updateTileLayoutMargins(int visualMarginStart, int visualMarginEnd) {
if (mUsingMediaPlayer) {
updateMargins((View) mRegularTileLayout, visualMarginStart, visualMarginEnd);
updateMargins((View) mHorizontalTileLayout, visualMarginStart, 0);
} else {
updateMargins((View) mTileLayout, visualMarginStart, visualMarginEnd);
}
}
@Override
protected void updatePadding() {
// QS Panel is setting a top padding by default, which we don't need.
}
@Override

View File

@@ -44,6 +44,7 @@ import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
@@ -145,6 +146,11 @@ public class QuickStatusBarHeader extends RelativeLayout implements
private boolean mHasTopCutout = false;
private int mRoundedCornerPadding = 0;
private int mContentMarginStart;
private int mContentMarginEnd;
private int mWaterfallTopInset;
private int mCutOutPaddingLeft;
private int mCutOutPaddingRight;
@Inject
public QuickStatusBarHeader(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
@@ -424,33 +430,42 @@ public class QuickStatusBarHeader extends RelativeLayout implements
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
// Handle padding of QuickStatusBarHeader
setPadding(mRoundedCornerPadding, getPaddingTop(), mRoundedCornerPadding,
getPaddingBottom());
// Handle padding of SystemIconsView
// Handle padding of the clock
DisplayCutout cutout = insets.getDisplayCutout();
Pair<Integer, Integer> cornerCutoutPadding = StatusBarWindowView.cornerCutoutMargins(
cutout, getDisplay());
Pair<Integer, Integer> padding =
StatusBarWindowView.paddingNeededForCutoutAndRoundedCorner(
cutout, cornerCutoutPadding, mRoundedCornerPadding);
final int waterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top;
int statusBarPaddingLeft = isLayoutRtl()
? getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end)
: getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start);
int statusBarPaddingRight = isLayoutRtl()
? getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start)
: getResources().getDimensionPixelSize(R.dimen.status_bar_padding_end);
mSystemIconsView.setPadding(
Math.max(padding.first + statusBarPaddingLeft - mRoundedCornerPadding, 0),
waterfallTopInset,
Math.max(padding.second + statusBarPaddingRight - mRoundedCornerPadding, 0),
0);
cutout, cornerCutoutPadding, -1);
mCutOutPaddingLeft = padding.first;
mCutOutPaddingRight = padding.second;
mWaterfallTopInset = cutout == null ? 0 : cutout.getWaterfallInsets().top;
updateClockPadding();
return super.onApplyWindowInsets(insets);
}
private void updateClockPadding() {
int clockPaddingLeft = 0;
int clockPaddingRight = 0;
// The clock might collide with cutouts, let's shift it out of the way.
// We only do that if the inset is bigger than our own padding, since it's nicer to
// align with
if (mCutOutPaddingLeft > 0) {
// if there's a cutout, let's use at least the rounded corner inset
int cutoutPadding = Math.max(mCutOutPaddingLeft, mRoundedCornerPadding);
int contentMarginLeft = isLayoutRtl() ? mContentMarginEnd : mContentMarginStart;
clockPaddingLeft = Math.max(cutoutPadding - contentMarginLeft, 0);
}
if (mCutOutPaddingRight > 0) {
// if there's a cutout, let's use at least the rounded corner inset
int cutoutPadding = Math.max(mCutOutPaddingRight, mRoundedCornerPadding);
int contentMarginRight = isLayoutRtl() ? mContentMarginStart : mContentMarginEnd;
clockPaddingRight = Math.max(cutoutPadding - contentMarginRight, 0);
}
mSystemIconsView.setPadding(clockPaddingLeft, mWaterfallTopInset, clockPaddingRight, 0);
}
@Override
@VisibleForTesting
public void onDetachedFromWindow() {
@@ -560,24 +575,27 @@ public class QuickStatusBarHeader extends RelativeLayout implements
return color == Color.WHITE ? 0 : 1;
}
public void setMargins(int sideMargins) {
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
// Prevents these views from getting set a margin.
// The Icon views all have the same padding set in XML to be aligned.
if (v == mSystemIconsView || v == mQuickQsStatusIcons || v == mHeaderQsPanel
|| v == mHeaderTextContainerView) {
continue;
}
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
lp.leftMargin = sideMargins;
lp.rightMargin = sideMargins;
}
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycle;
}
public void setContentMargins(int marginStart, int marginEnd) {
mContentMarginStart = marginStart;
mContentMarginEnd = marginEnd;
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
if (view == mHeaderQsPanel) {
// QS panel doesn't lays out some of its content full width
mHeaderQsPanel.setContentMargins(marginStart, marginEnd);
} else {
MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
lp.setMarginStart(marginStart);
lp.setMarginEnd(marginEnd);
view.setLayoutParams(lp);
}
}
updateClockPadding();
}
}

View File

@@ -96,7 +96,6 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
mCellMarginHorizontal = res.getDimensionPixelSize(R.dimen.qs_tile_margin_horizontal);
mCellMarginVertical= res.getDimensionPixelSize(R.dimen.qs_tile_margin_vertical);
mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top);
mSidePadding = res.getDimensionPixelOffset(R.dimen.qs_tile_layout_margin_side);
mMaxAllowedRows = Math.max(1, getResources().getInteger(R.integer.quick_settings_max_rows));
if (mLessRows) mMaxAllowedRows = Math.max(1, mMaxAllowedRows - 1);
if (mColumns != columns) {
@@ -120,7 +119,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
mRows = (numTiles + mColumns - 1) / mColumns;
}
mCellWidth =
(availableWidth - mSidePadding * 2 - (mCellMarginHorizontal * mColumns)) / mColumns;
(availableWidth - (mCellMarginHorizontal * mColumns)) / mColumns;
// Measure each QS tile.
View previousView = this;
@@ -204,7 +203,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout {
}
protected int getColumnStart(int column) {
return getPaddingStart() + mSidePadding + mCellMarginHorizontal / 2 +
return getPaddingStart() + mCellMarginHorizontal / 2 +
column * (mCellWidth + mCellMarginHorizontal);
}