1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.settings.dashboard; 18 19import android.content.Context; 20import android.content.res.Resources; 21import android.util.AttributeSet; 22import android.view.View; 23import android.view.ViewGroup; 24import com.android.settings.R; 25 26public class DashboardContainerView extends ViewGroup { 27 28 private float mCellGapX; 29 private float mCellGapY; 30 31 private int mNumRows; 32 private int mNumColumns; 33 34 public DashboardContainerView(Context context, AttributeSet attrs) { 35 super(context, attrs); 36 37 final Resources res = context.getResources(); 38 mCellGapX = res.getDimension(R.dimen.dashboard_cell_gap_x); 39 mCellGapY = res.getDimension(R.dimen.dashboard_cell_gap_y); 40 mNumColumns = res.getInteger(R.integer.dashboard_num_columns); 41 } 42 43 @Override 44 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 45 final int width = MeasureSpec.getSize(widthMeasureSpec); 46 final int availableWidth = (int) (width - getPaddingLeft() - getPaddingRight() - 47 (mNumColumns - 1) * mCellGapX); 48 float cellWidth = (float) Math.ceil(((float) availableWidth) / mNumColumns); 49 final int N = getChildCount(); 50 51 int cellHeight = 0; 52 int cursor = 0; 53 54 for (int i = 0; i < N; ++i) { 55 DashboardTileView v = (DashboardTileView) getChildAt(i); 56 if (v.getVisibility() == View.GONE) { 57 continue; 58 } 59 60 ViewGroup.LayoutParams lp = v.getLayoutParams(); 61 int colSpan = v.getColumnSpan(); 62 lp.width = (int) ((colSpan * cellWidth) + (colSpan - 1) * mCellGapX); 63 64 // Measure the child 65 int newWidthSpec = getChildMeasureSpec(widthMeasureSpec, 0, lp.width); 66 int newHeightSpec = getChildMeasureSpec(heightMeasureSpec, 0, lp.height); 67 v.measure(newWidthSpec, newHeightSpec); 68 69 // Save the cell height 70 if (cellHeight <= 0) { 71 cellHeight = v.getMeasuredHeight(); 72 } 73 74 lp.height = cellHeight; 75 76 cursor += colSpan; 77 } 78 79 mNumRows = (int) Math.ceil((float) cursor / mNumColumns); 80 final int newHeight = (int) ((mNumRows * cellHeight) + ((mNumRows - 1) * mCellGapY)) + 81 getPaddingTop() + getPaddingBottom(); 82 83 setMeasuredDimension(width, newHeight); 84 } 85 86 @Override 87 protected void onLayout(boolean changed, int l, int t, int r, int b) { 88 final int N = getChildCount(); 89 final boolean isLayoutRtl = isLayoutRtl(); 90 final int width = getWidth(); 91 92 int x = getPaddingStart(); 93 int y = getPaddingTop(); 94 int cursor = 0; 95 96 for (int i = 0; i < N; ++i) { 97 final DashboardTileView child = (DashboardTileView) getChildAt(i); 98 final ViewGroup.LayoutParams lp = child.getLayoutParams(); 99 if (child.getVisibility() == GONE) { 100 continue; 101 } 102 103 final int col = cursor % mNumColumns; 104 final int colSpan = child.getColumnSpan(); 105 106 final int childWidth = lp.width; 107 final int childHeight = lp.height; 108 109 int row = cursor / mNumColumns; 110 111 if (row == mNumRows - 1) { 112 child.setDividerVisibility(false); 113 } 114 115 // Push the item to the next row if it can't fit on this one 116 if ((col + colSpan) > mNumColumns) { 117 x = getPaddingStart(); 118 y += childHeight + mCellGapY; 119 row++; 120 } 121 122 final int childLeft = (isLayoutRtl) ? width - x - childWidth : x; 123 final int childRight = childLeft + childWidth; 124 125 final int childTop = y; 126 final int childBottom = childTop + childHeight; 127 128 // Layout the container 129 child.layout(childLeft, childTop, childRight, childBottom); 130 131 // Offset the position by the cell gap or reset the position and cursor when we 132 // reach the end of the row 133 cursor += child.getColumnSpan(); 134 if (cursor < (((row + 1) * mNumColumns))) { 135 x += childWidth + mCellGapX; 136 } else { 137 x = getPaddingStart(); 138 y += childHeight + mCellGapY; 139 } 140 } 141 } 142} 143