1 package com.android.systemui.qs; 2 3 import android.content.Context; 4 import android.content.res.Resources; 5 import android.util.AttributeSet; 6 import android.view.View; 7 import android.view.ViewGroup; 8 9 import com.android.systemui.R; 10 import com.android.systemui.qs.QSPanel.QSTileLayout; 11 import com.android.systemui.qs.QSPanel.TileRecord; 12 13 import java.util.ArrayList; 14 15 public class TileLayout extends ViewGroup implements QSTileLayout { 16 17 private static final float TILE_ASPECT = 1.2f; 18 19 private static final String TAG = "TileLayout"; 20 21 protected int mColumns; 22 protected int mCellWidth; 23 protected int mCellHeight; 24 protected int mCellMargin; 25 26 protected final ArrayList<TileRecord> mRecords = new ArrayList<>(); 27 private int mCellMarginTop; 28 private boolean mListening; 29 TileLayout(Context context)30 public TileLayout(Context context) { 31 this(context, null); 32 } 33 TileLayout(Context context, AttributeSet attrs)34 public TileLayout(Context context, AttributeSet attrs) { 35 super(context, attrs); 36 setFocusableInTouchMode(true); 37 updateResources(); 38 } 39 40 @Override getOffsetTop(TileRecord tile)41 public int getOffsetTop(TileRecord tile) { 42 return getTop(); 43 } 44 45 @Override setListening(boolean listening)46 public void setListening(boolean listening) { 47 if (mListening == listening) return; 48 mListening = listening; 49 for (TileRecord record : mRecords) { 50 record.tile.setListening(this, mListening); 51 } 52 } 53 addTile(TileRecord tile)54 public void addTile(TileRecord tile) { 55 mRecords.add(tile); 56 tile.tile.setListening(this, mListening); 57 addView(tile.tileView); 58 } 59 60 @Override removeTile(TileRecord tile)61 public void removeTile(TileRecord tile) { 62 mRecords.remove(tile); 63 tile.tile.setListening(this, false); 64 removeView(tile.tileView); 65 } 66 removeAllViews()67 public void removeAllViews() { 68 for (TileRecord record : mRecords) { 69 record.tile.setListening(this, false); 70 } 71 mRecords.clear(); 72 super.removeAllViews(); 73 } 74 updateResources()75 public boolean updateResources() { 76 final Resources res = mContext.getResources(); 77 final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns)); 78 mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height); 79 mCellMargin = res.getDimensionPixelSize(R.dimen.qs_tile_margin); 80 mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top); 81 if (mColumns != columns) { 82 mColumns = columns; 83 requestLayout(); 84 return true; 85 } 86 return false; 87 } 88 89 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)90 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 91 final int numTiles = mRecords.size(); 92 final int width = MeasureSpec.getSize(widthMeasureSpec); 93 final int rows = (numTiles + mColumns - 1) / mColumns; 94 mCellWidth = (width - (mCellMargin * (mColumns + 1))) / mColumns; 95 96 View previousView = this; 97 for (TileRecord record : mRecords) { 98 if (record.tileView.getVisibility() == GONE) continue; 99 record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight)); 100 previousView = record.tileView.updateAccessibilityOrder(previousView); 101 } 102 setMeasuredDimension(width, 103 (mCellHeight + mCellMargin) * rows + (mCellMarginTop - mCellMargin)); 104 } 105 exactly(int size)106 private static int exactly(int size) { 107 return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); 108 } 109 110 @Override onLayout(boolean changed, int l, int t, int r, int b)111 protected void onLayout(boolean changed, int l, int t, int r, int b) { 112 final int w = getWidth(); 113 boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 114 int row = 0; 115 int column = 0; 116 for (int i = 0; i < mRecords.size(); i++, column++) { 117 if (column == mColumns) { 118 row++; 119 column -= mColumns; 120 } 121 TileRecord record = mRecords.get(i); 122 int left = getColumnStart(column); 123 final int top = getRowTop(row); 124 int right; 125 if (isRtl) { 126 right = w - left; 127 left = right - mCellWidth; 128 } else { 129 right = left + mCellWidth; 130 } 131 record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight()); 132 } 133 } 134 getRowTop(int row)135 private int getRowTop(int row) { 136 return row * (mCellHeight + mCellMargin) + mCellMarginTop; 137 } 138 getColumnStart(int column)139 private int getColumnStart(int column) { 140 return column * (mCellWidth + mCellMargin) + mCellMargin; 141 } 142 } 143