OSDN Git Service

Change how PagedTileLayout is measured
authorFabian Kozynski <kozynski@google.com>
Mon, 15 Apr 2019 18:09:43 +0000 (14:09 -0400)
committerFabian Kozynski <kozynski@google.com>
Thu, 18 Apr 2019 15:25:07 +0000 (11:25 -0400)
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

packages/SystemUI/res/layout/qs_paged_tile_layout.xml
packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
packages/SystemUI/src/com/android/systemui/qs/TileLayout.java

index e44fbcf..8878786 100644 (file)
@@ -18,7 +18,7 @@
 <com.android.systemui.qs.PagedTileLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="0dp"
     android:layout_weight="1"
     android:clipChildren="true"
     android:paddingBottom="@dimen/qs_paged_tile_layout_padding_bottom">
index ebc3a6a..e22a21a 100644 (file)
@@ -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) {
index dbd3042..f0413cd 100644 (file)
@@ -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();
index d6e0306..ddefdf6 100644 (file)
@@ -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;
     }
index 1dd729d..8aacd72 100644 (file)
@@ -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) {