From 520ea0673e1dd44fc0cac04ab1d0ded5b8a67a52 Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Tue, 18 Aug 2015 14:53:06 -0400 Subject: [PATCH] Some QS refactoring Get the bit about tiles out into its own place. This will make it easier to experiment with new layouts, and to hide/show other elements as necessary without lots of layout work. Change-Id: I32752df1881e4e3c693730284f8608102abdc04b --- .../src/com/android/systemui/qs/QSPanel.java | 160 +++--------------- .../com/android/systemui/qs/TileLayout.java | 127 ++++++++++++++ 2 files changed, 152 insertions(+), 135 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/qs/TileLayout.java diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 94d517086789c..b640cf17914b5 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -30,7 +30,9 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; +import android.widget.FrameLayout; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; @@ -46,8 +48,7 @@ import java.util.ArrayList; import java.util.Collection; /** View that represents the quick settings tile panel. **/ -public class QSPanel extends ViewGroup { - private static final float TILE_ASPECT = 1.2f; +public class QSPanel extends FrameLayout { private final Context mContext; protected final ArrayList mRecords = new ArrayList(); @@ -59,15 +60,8 @@ public class QSPanel extends ViewGroup { private final QSDetailClipper mClipper; private final H mHandler = new H(); - private int mColumns; - private int mCellWidth; - private int mCellHeight; - private int mLargeCellWidth; - private int mLargeCellHeight; private int mPanelPaddingBottom; - private int mDualTileUnderlap; private int mBrightnessPaddingTop; - private int mGridHeight; private boolean mExpanded; private boolean mListening; private boolean mClosingDetail; @@ -80,6 +74,9 @@ public class QSPanel extends ViewGroup { private QSFooter mFooter; private boolean mGridContentVisible = true; + private LinearLayout mQsContainer; + private TileLayout mTileLayout; + public QSPanel(Context context) { this(context, null); } @@ -99,8 +96,19 @@ public class QSPanel extends ViewGroup { R.layout.quick_settings_brightness_dialog, this, false); mFooter = new QSFooter(this, context); addView(mDetail); - addView(mBrightnessView); - addView(mFooter.getView()); + + mQsContainer = new LinearLayout(mContext); + mQsContainer.setOrientation(LinearLayout.VERTICAL); + mQsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.WRAP_CONTENT)); + + addView(mQsContainer); + + mTileLayout = new TileLayout(mContext, mRecords); + + mQsContainer.addView(mBrightnessView); + mQsContainer.addView(mTileLayout); + mQsContainer.addView(mFooter.getView()); mClipper = new QSDetailClipper(mDetail); updateResources(); @@ -146,18 +154,9 @@ public class QSPanel extends ViewGroup { public void updateResources() { final Resources res = mContext.getResources(); - final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns)); - mCellHeight = res.getDimensionPixelSize(R.dimen.qs_tile_height); - mCellWidth = (int)(mCellHeight * TILE_ASPECT); - mLargeCellHeight = res.getDimensionPixelSize(R.dimen.qs_dual_tile_height); - mLargeCellWidth = (int)(mLargeCellHeight * TILE_ASPECT); mPanelPaddingBottom = res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom); - mDualTileUnderlap = res.getDimensionPixelSize(R.dimen.qs_dual_tile_padding_vertical); mBrightnessPaddingTop = res.getDimensionPixelSize(R.dimen.qs_brightness_padding_top); - if (mColumns != columns) { - mColumns = columns; - postInvalidate(); - } + mQsContainer.setPadding(0, mBrightnessPaddingTop, 0, mPanelPaddingBottom); for (TileRecord r : mRecords) { r.tile.clearState(); } @@ -165,6 +164,7 @@ public class QSPanel extends ViewGroup { refreshAllTiles(); } updateDetailText(); + mTileLayout.updateResources(); } @Override @@ -245,9 +245,6 @@ public class QSPanel extends ViewGroup { } private void handleSetTileVisibility(View v, int visibility) { - if (visibility == VISIBLE && !mGridContentVisible) { - visibility = INVISIBLE; - } if (visibility == v.getVisibility()) return; v.setVisibility(visibility); } @@ -332,7 +329,7 @@ public class QSPanel extends ViewGroup { r.tile.refreshState(); mRecords.add(r); - addView(r.tileView); + mTileLayout.addView(r.tileView); } public boolean isShowingDetail() { @@ -348,7 +345,7 @@ public class QSPanel extends ViewGroup { } public int getGridHeight() { - return mGridHeight; + return mQsContainer.getMeasuredHeight(); } private void handleShowDetail(Record r, boolean show) { @@ -374,7 +371,7 @@ public class QSPanel extends ViewGroup { } r.tile.setDetailListening(show); int x = r.tileView.getLeft() + r.tileView.getWidth() / 2; - int y = r.tileView.getTop() + r.tileView.getHeight() / 2; + int y = r.tileView.getTop() + mTileLayout.getTop() + r.tileView.getHeight() / 2; handleShowDetailImpl(r, show, x, y); } @@ -427,13 +424,7 @@ public class QSPanel extends ViewGroup { private void setGridContentVisibility(boolean visible) { int newVis = visible ? VISIBLE : INVISIBLE; - for (int i = 0; i < mRecords.size(); i++) { - TileRecord tileRecord = mRecords.get(i); - if (tileRecord.tileView.getVisibility() != GONE) { - tileRecord.tileView.setVisibility(newVis); - } - } - mBrightnessView.setVisibility(newVis); + mQsContainer.setVisibility(newVis); if (mGridContentVisible != visible) { MetricsLogger.visibility(mContext, MetricsLogger.QS_PANEL, newVis); } @@ -449,107 +440,6 @@ public class QSPanel extends ViewGroup { } } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int width = MeasureSpec.getSize(widthMeasureSpec); - mBrightnessView.measure(exactly(width), MeasureSpec.UNSPECIFIED); - final int brightnessHeight = mBrightnessView.getMeasuredHeight() + mBrightnessPaddingTop; - mFooter.getView().measure(exactly(width), MeasureSpec.UNSPECIFIED); - int r = -1; - int c = -1; - int rows = 0; - boolean rowIsDual = false; - for (TileRecord record : mRecords) { - if (record.tileView.getVisibility() == GONE) continue; - // wrap to next column if we've reached the max # of columns - // also don't allow dual + single tiles on the same row - if (r == -1 || c == (mColumns - 1) || rowIsDual != record.tile.supportsDualTargets()) { - r++; - c = 0; - rowIsDual = record.tile.supportsDualTargets(); - } else { - c++; - } - record.row = r; - record.col = c; - rows = r + 1; - } - - View previousView = mBrightnessView; - for (TileRecord record : mRecords) { - if (record.tileView.setDual(record.tile.supportsDualTargets())) { - record.tileView.handleStateChanged(record.tile.getState()); - } - if (record.tileView.getVisibility() == GONE) continue; - final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth; - final int ch = record.row == 0 ? mLargeCellHeight : mCellHeight; - record.tileView.measure(exactly(cw), exactly(ch)); - previousView = record.tileView.updateAccessibilityOrder(previousView); - } - int h = rows == 0 ? brightnessHeight : (getRowTop(rows) + mPanelPaddingBottom); - if (mFooter.hasFooter()) { - h += mFooter.getView().getMeasuredHeight(); - } - mDetail.measure(exactly(width), MeasureSpec.UNSPECIFIED); - if (mDetail.getMeasuredHeight() < h) { - mDetail.measure(exactly(width), exactly(h)); - } - mGridHeight = h; - setMeasuredDimension(width, Math.max(h, mDetail.getMeasuredHeight())); - } - - private static int exactly(int size) { - return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - final int w = getWidth(); - mBrightnessView.layout(0, mBrightnessPaddingTop, - mBrightnessView.getMeasuredWidth(), - mBrightnessPaddingTop + mBrightnessView.getMeasuredHeight()); - boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; - for (TileRecord record : mRecords) { - if (record.tileView.getVisibility() == GONE) continue; - final int cols = getColumnCount(record.row); - final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth; - final int extra = (w - cw * cols) / (cols + 1); - int left = record.col * cw + (record.col + 1) * extra; - final int top = getRowTop(record.row); - int right; - int tileWith = record.tileView.getMeasuredWidth(); - if (isRtl) { - right = w - left; - left = right - tileWith; - } else { - right = left + tileWith; - } - record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight()); - } - final int dh = Math.max(mDetail.getMeasuredHeight(), getMeasuredHeight()); - mDetail.layout(0, 0, mDetail.getMeasuredWidth(), dh); - if (mFooter.hasFooter()) { - View footer = mFooter.getView(); - footer.layout(0, getMeasuredHeight() - footer.getMeasuredHeight(), - footer.getMeasuredWidth(), getMeasuredHeight()); - } - } - - private int getRowTop(int row) { - if (row <= 0) return mBrightnessView.getMeasuredHeight() + mBrightnessPaddingTop; - return mBrightnessView.getMeasuredHeight() + mBrightnessPaddingTop - + mLargeCellHeight - mDualTileUnderlap + (row - 1) * mCellHeight; - } - - private int getColumnCount(int row) { - int cols = 0; - for (TileRecord record : mRecords) { - if (record.tileView.getVisibility() == GONE) continue; - if (record.row == row) cols++; - } - return cols; - } - private void fireShowingDetail(QSTile.DetailAdapter detail) { if (mCallback != null) { mCallback.onShowingDetail(detail); diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java new file mode 100644 index 0000000000000..02b8fe3f31295 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java @@ -0,0 +1,127 @@ +package com.android.systemui.qs; + +import android.content.Context; +import android.content.res.Resources; +import android.view.View; +import android.view.ViewGroup; + +import com.android.systemui.R; +import com.android.systemui.qs.QSPanel.TileRecord; + +import java.util.ArrayList; + +public class TileLayout extends ViewGroup { + + private static final float TILE_ASPECT = 1.2f; + + private static final String TAG = "TileLayout"; + + private int mDualTileUnderlap; + private int mColumns; + private int mCellWidth; + private int mCellHeight; + private int mLargeCellWidth; + private int mLargeCellHeight; + + private final ArrayList mRecords; + + public TileLayout(Context context, ArrayList records) { + super(context); + mRecords = records; + updateResources(); + } + + public void updateResources() { + final Resources res = mContext.getResources(); + final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns)); + mCellHeight = res.getDimensionPixelSize(R.dimen.qs_tile_height); + mCellWidth = (int)(mCellHeight * TILE_ASPECT); + mLargeCellHeight = res.getDimensionPixelSize(R.dimen.qs_dual_tile_height); + mLargeCellWidth = (int)(mLargeCellHeight * TILE_ASPECT); + mDualTileUnderlap = res.getDimensionPixelSize(R.dimen.qs_dual_tile_padding_vertical); + if (mColumns != columns) { + mColumns = columns; + postInvalidate(); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final int width = MeasureSpec.getSize(widthMeasureSpec); + int r = -1; + int c = -1; + int rows = 0; + boolean rowIsDual = false; + for (TileRecord record : mRecords) { + if (record.tileView.getVisibility() == GONE) continue; + // wrap to next column if we've reached the max # of columns + // also don't allow dual + single tiles on the same row + if (r == -1 || c == (mColumns - 1) || rowIsDual != record.tile.supportsDualTargets()) { + r++; + c = 0; + rowIsDual = record.tile.supportsDualTargets(); + } else { + c++; + } + record.row = r; + record.col = c; + rows = r + 1; + } + + View previousView = this; + for (TileRecord record : mRecords) { + if (record.tileView.setDual(record.tile.supportsDualTargets())) { + record.tileView.handleStateChanged(record.tile.getState()); + } + if (record.tileView.getVisibility() == GONE) continue; + final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth; + final int ch = record.row == 0 ? mLargeCellHeight : mCellHeight; + record.tileView.measure(exactly(cw), exactly(ch)); + previousView = record.tileView.updateAccessibilityOrder(previousView); + } + int h = rows == 0 ? 0 : getRowTop(rows); + setMeasuredDimension(width, h); + } + + private static int exactly(int size) { + return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + final int w = getWidth(); + boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; + for (TileRecord record : mRecords) { + if (record.tileView.getVisibility() == GONE) continue; + final int cols = getColumnCount(record.row); + final int cw = record.row == 0 ? mLargeCellWidth : mCellWidth; + final int extra = (w - cw * cols) / (cols + 1); + int left = record.col * cw + (record.col + 1) * extra; + final int top = getRowTop(record.row); + int right; + int tileWith = record.tileView.getMeasuredWidth(); + if (isRtl) { + right = w - left; + left = right - tileWith; + } else { + right = left + tileWith; + } + record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight()); + } + } + + private int getRowTop(int row) { + if (row <= 0) return 0; + return mLargeCellHeight - mDualTileUnderlap + (row - 1) * mCellHeight; + } + + private int getColumnCount(int row) { + int cols = 0; + for (TileRecord record : mRecords) { + if (record.tileView.getVisibility() == GONE) continue; + if (record.row == row) cols++; + } + return cols; + } + +}