QuickSettingsContainerView.java revision f4b5ab193c95675c07b8e361846d21d79571da0e
1d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung/* 2d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * Copyright (C) 2012 The Android Open Source Project 3d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * 4d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * you may not use this file except in compliance with the License. 6d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * You may obtain a copy of the License at 7d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * 8d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 9d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * 10d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * Unless required by applicable law or agreed to in writing, software 11d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * See the License for the specific language governing permissions and 14d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * limitations under the License. 15d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung */ 16d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 17d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungpackage com.android.systemui.statusbar.phone; 18d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 19d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.animation.LayoutTransition; 20d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.content.Context; 21d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.content.res.Resources; 22d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.util.AttributeSet; 23d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.view.ViewGroup; 24d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport android.widget.FrameLayout; 25d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 26d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungimport com.android.systemui.R; 27d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 28d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung/** 29d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung * 30d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung */ 31d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chungclass QuickSettingsContainerView extends FrameLayout { 32d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 33d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // The number of columns in the QuickSettings grid 34d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung private int mNumColumns; 35d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 36d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // The gap between tiles in the QuickSettings grid 37d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung private float mCellGap; 38d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 39d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung public QuickSettingsContainerView(Context context, AttributeSet attrs) { 40d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung super(context, attrs); 41d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 42d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung updateResources(); 43d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 44d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 45d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung @Override 46d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung protected void onFinishInflate() { 47d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung super.onFinishInflate(); 48d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 49d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // TODO: Setup the layout transitions 50d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung LayoutTransition transitions = getLayoutTransition(); 51d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 52d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 53d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung void updateResources() { 54d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung Resources r = getContext().getResources(); 55d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung mCellGap = r.getDimension(R.dimen.quick_settings_cell_gap); 56d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung mNumColumns = r.getInteger(R.integer.quick_settings_num_columns); 57d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung requestLayout(); 58d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 59d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 60d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung @Override 61d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 62d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Calculate the cell width dynamically 63d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int width = MeasureSpec.getSize(widthMeasureSpec); 64d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int height = MeasureSpec.getSize(heightMeasureSpec); 65d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int availableWidth = (int) (width - getPaddingLeft() - getPaddingRight() - 66d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung (mNumColumns - 1) * mCellGap); 67f4b5ab193c95675c07b8e361846d21d79571da0eWinson Chung float cellWidth = (float) Math.ceil(((float) availableWidth) / mNumColumns); 68d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 69d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Update each of the children's widths accordingly to the cell width 70d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int N = getChildCount(); 71d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int cellHeight = 0; 72d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int cursor = 0; 73d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung for (int i = 0; i < N; ++i) { 74d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Update the child's width 75d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i); 76d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) v.getLayoutParams(); 77d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int colSpan = v.getColumnSpan(); 78d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung lp.width = (int) ((colSpan * cellWidth) + (colSpan - 1) * mCellGap); 79d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 80d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Measure the child 81eaa5ab01a122ceb907a2bead35077331d604021bWinson Chung int newWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); 82eaa5ab01a122ceb907a2bead35077331d604021bWinson Chung int newHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); 83d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung v.measure(newWidthSpec, newHeightSpec); 84d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 85d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Save the cell height 86d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung if (cellHeight <= 0) { 87d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung cellHeight = v.getMeasuredHeight(); 88d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 89d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung cursor += colSpan; 90d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 91d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 92d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Set the measured dimensions. We always fill the tray width, but wrap to the height of 93d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // all the tiles. 94d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int numRows = (int) Math.ceil((float) cursor / mNumColumns); 95d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int newHeight = (int) ((numRows * cellHeight) + ((numRows - 1) * mCellGap)) + 96d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung getPaddingTop() + getPaddingBottom(); 97d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung setMeasuredDimension(width, newHeight); 98d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 99d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 100d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung @Override 101d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 102d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int N = getChildCount(); 103d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int x = getPaddingLeft(); 104d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int y = getPaddingTop(); 105d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int cursor = 0; 106d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung for (int i = 0; i < N; ++i) { 107d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung QuickSettingsTileView v = (QuickSettingsTileView) getChildAt(i); 108d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) v.getLayoutParams(); 109d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung if (v.getVisibility() != GONE) { 110d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int col = cursor % mNumColumns; 111d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int colSpan = v.getColumnSpan(); 112d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung int row = (int) (cursor / mNumColumns); 113d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 114d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Push the item to the next row if it can't fit on this one 115d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung if ((col + colSpan) > mNumColumns) { 116d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung x = getPaddingLeft(); 117d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung y += lp.height + mCellGap; 118d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung row++; 119d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 120d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 121d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Layout the container 122d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung v.layout(x, y, x + lp.width, y + lp.height); 123d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung 124d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // Offset the position by the cell gap or reset the position and cursor when we 125d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung // reach the end of the row 126d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung cursor += v.getColumnSpan(); 127d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung if (cursor < (((row + 1) * mNumColumns))) { 128d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung x += lp.width + mCellGap; 129d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } else { 130d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung x = getPaddingLeft(); 131d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung y += lp.height + mCellGap; 132d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 133d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 134d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 135d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung } 136d63c59786509aadd6a8d0c5cb45ed696339f16b7Winson Chung}