1package com.android.systemui.qs; 2 3import android.content.Context; 4import android.content.res.Resources; 5import android.util.AttributeSet; 6import android.view.View; 7import android.view.ViewGroup; 8 9import com.android.systemui.R; 10import com.android.systemui.qs.QSPanel.QSTileLayout; 11import com.android.systemui.qs.QSPanel.TileRecord; 12 13import java.util.ArrayList; 14 15public 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 30 public TileLayout(Context context) { 31 this(context, null); 32 } 33 34 public TileLayout(Context context, AttributeSet attrs) { 35 super(context, attrs); 36 setFocusableInTouchMode(true); 37 updateResources(); 38 } 39 40 @Override 41 public int getOffsetTop(TileRecord tile) { 42 return getTop(); 43 } 44 45 @Override 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 54 public void addTile(TileRecord tile) { 55 mRecords.add(tile); 56 tile.tile.setListening(this, mListening); 57 addView(tile.tileView); 58 } 59 60 @Override 61 public void removeTile(TileRecord tile) { 62 mRecords.remove(tile); 63 tile.tile.setListening(this, false); 64 removeView(tile.tileView); 65 } 66 67 public void removeAllViews() { 68 for (TileRecord record : mRecords) { 69 record.tile.setListening(this, false); 70 } 71 mRecords.clear(); 72 super.removeAllViews(); 73 } 74 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 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 int height = (mCellHeight + mCellMargin) * rows + (mCellMarginTop - mCellMargin); 103 if (height < 0) height = 0; 104 setMeasuredDimension(width, height); 105 } 106 107 private static int exactly(int size) { 108 return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); 109 } 110 111 @Override 112 protected void onLayout(boolean changed, int l, int t, int r, int b) { 113 final int w = getWidth(); 114 boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 115 int row = 0; 116 int column = 0; 117 for (int i = 0; i < mRecords.size(); i++, column++) { 118 if (column == mColumns) { 119 row++; 120 column -= mColumns; 121 } 122 TileRecord record = mRecords.get(i); 123 int left = getColumnStart(column); 124 final int top = getRowTop(row); 125 int right; 126 if (isRtl) { 127 right = w - left; 128 left = right - mCellWidth; 129 } else { 130 right = left + mCellWidth; 131 } 132 record.tileView.layout(left, top, right, top + record.tileView.getMeasuredHeight()); 133 } 134 } 135 136 private int getRowTop(int row) { 137 return row * (mCellHeight + mCellMargin) + mCellMarginTop; 138 } 139 140 private int getColumnStart(int column) { 141 return column * (mCellWidth + mCellMargin) + mCellMargin; 142 } 143} 144