From 72cd84a9790770d162c3a6cf87e891dd4ed8420b Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Mon, 15 Apr 2019 14:09:43 -0400 Subject: [PATCH] Change how PagedTileLayout is measured The change makes PagedTileLayout only use excess space from QSPanel after other views have been measured and the padding has been accounted for (see LinearLayout#measureVertical). PagedTileLayout caches the last height to be measured so as to minimize the number of times the number of rows is recalculated (and prevent loops). Also, fixed the calculation in TileLayout#updateMaxRows to match the height calculation in TileLayout#onMeasure. Test: manual, stress testing with multiple pages, adding and removing tiles, starting and disconnecting VPN, changing display size Bug:122714773 Change-Id: I5c85f03cfc79e341244d213fd92307821db80889 --- .../res/layout/qs_paged_tile_layout.xml | 2 +- .../android/systemui/qs/PagedTileLayout.java | 6 +++++- .../android/systemui/qs/QSContainerImpl.java | 4 +++- .../src/com/android/systemui/qs/QSPanel.java | 18 ++++++++++++++++++ .../com/android/systemui/qs/TileLayout.java | 3 ++- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml index e44fbcfd122f5..887878631de77 100644 --- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml +++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml @@ -18,7 +18,7 @@ diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index ebc3a6adaeee5..e22a21ad1fedf 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -63,6 +63,7 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { private int mLayoutDirection; private int mHorizontalClipBound; private final Rect mClippingRect; + private int mLastMaxHeight = -1; public PagedTileLayout(Context context, AttributeSet attrs) { super(context, attrs); @@ -303,8 +304,11 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int nTiles = mTiles.size(); - if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) { + // If we have no reason to recalculate the number of rows, skip this step. In particular, + // if the height passed by its parent is the same as the last time, we try not to remeasure. + if (mDistributeTiles || mLastMaxHeight != MeasureSpec.getSize(heightMeasureSpec)) { + mLastMaxHeight = MeasureSpec.getSize(heightMeasureSpec); // Only change the pages if the number of rows or columns (from updateResources) has // changed or the tiles have changed if (mPages.get(0).updateMaxRows(heightMeasureSpec, nTiles) || mDistributeTiles) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index dbd3042336017..f0413cd6651bd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -103,7 +103,9 @@ public class QSContainerImpl extends FrameLayout { if (navBelow) { maxQs -= getResources().getDimensionPixelSize(R.dimen.navigation_bar_height); } - mQSPanel.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maxQs, MeasureSpec.AT_MOST)); + // 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(); int height = layoutParams.topMargin + layoutParams.bottomMargin + mQSPanel.getMeasuredHeight() + getPaddingBottom(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index d6e03060c7f7e..ddefdf6461599 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -128,6 +128,24 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne addView(mDivider); } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // We want all the logic of LinearLayout#onMeasure, and for it to assign the excess space + // not used by the other children to PagedTileLayout. However, in this case, LinearLayout + // assumes that PagedTileLayout would use all the excess space. This is not the case as + // PagedTileLayout height is quantized (because it shows a certain number of rows). + // Therefore, after everything is measured, we need to make sure that we add up the correct + // total height + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int height = getPaddingBottom() + getPaddingTop(); + int numChildren = getChildCount(); + for (int i = 0; i < numChildren; i++) { + View child = getChildAt(i); + if (child.getVisibility() != View.GONE) height += child.getMeasuredHeight(); + } + setMeasuredDimension(getMeasuredWidth(), height); + } + public View getDivider() { return mDivider; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java index 1dd729d0624c0..8aacd725ceb49 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java @@ -137,7 +137,8 @@ public class TileLayout extends ViewGroup implements QSTileLayout { * @param tilesCount Upper limit on the number of tiles to show. to prevent empty rows. */ public boolean updateMaxRows(int heightMeasureSpec, int tilesCount) { - final int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mCellMarginTop; + final int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mCellMarginTop + + mCellMarginVertical; final int previousRows = mRows; mRows = availableHeight / (mCellHeight + mCellMarginVertical); if (mRows >= mMaxAllowedRows) {