19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.widget; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.R; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.SparseBooleanArray; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Pattern; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>A layout that arranges its children into rows and columns. 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A TableLayout consists of a number of {@link android.widget.TableRow} objects, 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each defining a row (actually, you can have other children, which will be 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * explained below). TableLayout containers do not display border lines for 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * their rows, columns, or cells. Each row has zero or more cells; each cell can 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hold one {@link android.view.View View} object. The table has as many columns 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the row with the most cells. A table can leave cells empty. Cells can span 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * columns, as they can in HTML.</p> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The width of a column is defined by the row with the widest cell in that 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * column. However, a TableLayout can specify certain columns as shrinkable or 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stretchable by calling 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setColumnShrinkable(int, boolean) setColumnShrinkable()} 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #setColumnStretchable(int, boolean) setColumnStretchable()}. If 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * marked as shrinkable, the column width can be shrunk to fit the table into 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * its parent object. If marked as stretchable, it can expand in width to fit 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * any extra space. The total width of the table is defined by its parent 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * container. It is important to remember that a column can be both shrinkable 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and stretchable. In such a situation, the column will change its size to 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * always use up the available space, but never more. Finally, you can hide a 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * column by calling 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setColumnCollapsed(int,boolean) setColumnCollapsed()}.</p> 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The children of a TableLayout cannot specify the <code>layout_width</code> 55980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * attribute. Width is always <code>MATCH_PARENT</code>. However, the 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>layout_height</code> attribute can be defined by a child; default value 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is {@link android.widget.TableLayout.LayoutParams#WRAP_CONTENT}. If the child 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is a {@link android.widget.TableRow}, then the height is always 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.widget.TableLayout.LayoutParams#WRAP_CONTENT}.</p> 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> Cells must be added to a row in increasing column order, both in code and 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * XML. Column numbers are zero-based. If you don't specify a column number for 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a child cell, it will autoincrement to the next available column. If you skip 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a column number, it will be considered an empty cell in that row. See the 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * TableLayout examples in ApiDemos for examples of creating tables in XML.</p> 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Although the typical child of a TableLayout is a TableRow, you can 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * actually use any View subclass as a direct child of TableLayout. The View 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be displayed as a single row that spans all the table columns.</p> 7041ec65355bd6ded652769725b276d47c54a0d913Scott Main * 7141ec65355bd6ded652769725b276d47c54a0d913Scott Main * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-tablelayout.html">Table 7241ec65355bd6ded652769725b276d47c54a0d913Scott Main * Layout tutorial</a>.</p> 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class TableLayout extends LinearLayout { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int[] mMaxWidths; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SparseBooleanArray mStretchableColumns; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SparseBooleanArray mShrinkableColumns; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private SparseBooleanArray mCollapsedColumns; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mShrinkAllColumns; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStretchAllColumns; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private TableLayout.PassThroughHierarchyChangeListener mPassThroughListener; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mInitialized; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Creates a new TableLayout for the given context.</p> 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application environment 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public TableLayout(Context context) { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initTableLayout(); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Creates a new TableLayout for the given context and with the 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * specified set attributes.</p> 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application environment 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param attrs a collection of attributes 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public TableLayout(Context context, AttributeSet attrs) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TableLayout); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String stretchedColumns = a.getString(R.styleable.TableLayout_stretchColumns); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stretchedColumns != null) { 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stretchedColumns.charAt(0) == '*') { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStretchAllColumns = true; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStretchableColumns = parseColumns(stretchedColumns); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String shrinkedColumns = a.getString(R.styleable.TableLayout_shrinkColumns); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (shrinkedColumns != null) { 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (shrinkedColumns.charAt(0) == '*') { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShrinkAllColumns = true; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShrinkableColumns = parseColumns(shrinkedColumns); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String collapsedColumns = a.getString(R.styleable.TableLayout_collapseColumns); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (collapsedColumns != null) { 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCollapsedColumns = parseColumns(collapsedColumns); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initTableLayout(); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Parses a sequence of columns ids defined in a CharSequence with the 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * following pattern (regex): \d+(\s*,\s*\d+)*</p> 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Examples: "1" or "13, 7, 6" or "".</p> 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The result of the parsing is stored in a sparse boolean array. The 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * parsed column ids are used as the keys of the sparse array. The values 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * are always true.</p> 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sequence a sequence of column ids, can be empty but not null 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return a sparse array of boolean mapping column indexes to the columns 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * collapse state 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static SparseBooleanArray parseColumns(String sequence) { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SparseBooleanArray columns = new SparseBooleanArray(); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Pattern pattern = Pattern.compile("\\s*,\\s*"); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] columnDefs = pattern.split(sequence); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String columnIdentifier : columnDefs) { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int columnIndex = Integer.parseInt(columnIdentifier); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // only valid, i.e. positive, columns indexes are handled 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (columnIndex >= 0) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // putting true in this sparse array indicates that the 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // column index was defined in the XML file 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project columns.put(columnIndex, true); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException e) { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we just ignore columns that don't exist 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return columns; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Performs initialization common to prorgrammatic use and XML use of 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this widget.</p> 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void initTableLayout() { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCollapsedColumns == null) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCollapsedColumns = new SparseBooleanArray(); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStretchableColumns == null) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStretchableColumns = new SparseBooleanArray(); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShrinkableColumns == null) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShrinkableColumns = new SparseBooleanArray(); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPassThroughListener = new PassThroughHierarchyChangeListener(); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure to call the parent class method to avoid potential 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // infinite loops 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setOnHierarchyChangeListener(mPassThroughListener); 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInitialized = true; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnHierarchyChangeListener( 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OnHierarchyChangeListener listener) { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the user listener is delegated to our pass-through listener 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPassThroughListener.mOnHierarchyChangeListener = listener; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void requestRowsLayout() { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInitialized) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getChildAt(i).requestLayout(); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestLayout() { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInitialized) { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = getChildCount(); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getChildAt(i).forceLayout(); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.requestLayout(); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether all columns are shrinkable or not.</p> 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if all columns are shrinkable, false otherwise 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShrinkAllColumns() { 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mShrinkAllColumns; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Convenience method to mark all columns as shrinkable.</p> 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param shrinkAllColumns true to mark all columns shrinkable 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_shrinkColumns 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setShrinkAllColumns(boolean shrinkAllColumns) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShrinkAllColumns = shrinkAllColumns; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether all columns are stretchable or not.</p> 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if all columns are stretchable, false otherwise 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStretchAllColumns() { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStretchAllColumns; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Convenience method to mark all columns as stretchable.</p> 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param stretchAllColumns true to mark all columns stretchable 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_stretchColumns 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setStretchAllColumns(boolean stretchAllColumns) { 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStretchAllColumns = stretchAllColumns; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Collapses or restores a given column. When collapsed, a column 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * does not appear on screen and the extra space is reclaimed by the 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * other columns. A column is collapsed/restored only when it belongs to 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a {@link android.widget.TableRow}.</p> 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Calling this method requests a layout operation.</p> 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isCollapsed true if the column must be collapsed, false otherwise 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_collapseColumns 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColumnCollapsed(int columnIndex, boolean isCollapsed) { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // update the collapse status of the column 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCollapsedColumns.put(columnIndex, isCollapsed); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = getChildCount(); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View view = getChildAt(i); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (view instanceof TableRow) { 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((TableRow) view).setColumnCollapsed(columnIndex, isCollapsed); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the collapsed state of the specified column.</p> 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the column is collapsed, false otherwise 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isColumnCollapsed(int columnIndex) { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCollapsedColumns.get(columnIndex); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Makes the given column stretchable or not. When stretchable, a column 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * takes up as much as available space as possible in its row.</p> 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Calling this method requests a layout operation.</p> 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isStretchable true if the column must be stretchable, 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * false otherwise. Default is false. 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_stretchColumns 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColumnStretchable(int columnIndex, boolean isStretchable) { 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStretchableColumns.put(columnIndex, isStretchable); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns whether the specified column is stretchable or not.</p> 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the column is stretchable, false otherwise 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isColumnStretchable(int columnIndex) { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStretchAllColumns || mStretchableColumns.get(columnIndex); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Makes the given column shrinkable or not. When a row is too wide, the 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * table can reclaim extra space from shrinkable columns.</p> 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Calling this method requests a layout operation.</p> 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isShrinkable true if the column must be shrinkable, 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * false otherwise. Default is false. 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_shrinkColumns 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColumnShrinkable(int columnIndex, boolean isShrinkable) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShrinkableColumns.put(columnIndex, isShrinkable); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns whether the specified column is shrinkable or not.</p> 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the column is shrinkable, false otherwise. Default is false. 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isColumnShrinkable(int columnIndex) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mShrinkAllColumns || mShrinkableColumns.get(columnIndex); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Applies the columns collapse status to a new row added to this 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * table. This method is invoked by PassThroughHierarchyChangeListener 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * upon child insertion.</p> 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This method only applies to {@link android.widget.TableRow} 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instances.</p> 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param child the newly added child 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void trackCollapsedColumns(View child) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child instanceof TableRow) { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final TableRow row = (TableRow) child; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SparseBooleanArray collapsedColumns = mCollapsedColumns; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = collapsedColumns.size(); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int columnIndex = collapsedColumns.keyAt(i); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isCollapsed = collapsedColumns.valueAt(i); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the collapse status is set only when the column should be 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // collapsed; otherwise, this might affect the default 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // visibility of the row's children 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isCollapsed) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row.setColumnCollapsed(columnIndex, isCollapsed); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View child) { 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.addView(child); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View child, int index) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.addView(child, index); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View child, ViewGroup.LayoutParams params) { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.addView(child, params); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View child, int index, ViewGroup.LayoutParams params) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.addView(child, index, params); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // enforce vertical layout 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project measureVertical(widthMeasureSpec, heightMeasureSpec); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onLayout(boolean changed, int l, int t, int r, int b) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // enforce vertical layout 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project layoutVertical(); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void measureChildBeforeLayout(View child, int childIndex, 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthMeasureSpec, int totalWidth, 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int heightMeasureSpec, int totalHeight) { 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when the measured child is a table row, we force the width of its 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // children with the widths computed in findLargestCells() 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child instanceof TableRow) { 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((TableRow) child).setColumnsWidthConstraints(mMaxWidths); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.measureChildBeforeLayout(child, childIndex, 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthMeasureSpec, totalWidth, heightMeasureSpec, totalHeight); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void measureVertical(int widthMeasureSpec, int heightMeasureSpec) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project findLargestCells(widthMeasureSpec); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shrinkAndStretchColumns(widthMeasureSpec); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.measureVertical(widthMeasureSpec, heightMeasureSpec); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Finds the largest cell in each column. For each column, the width of 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the largest cell is applied to all the other cells.</p> 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthMeasureSpec the measure constraint imposed by our parent 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void findLargestCells(int widthMeasureSpec) { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean firstRow = true; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // find the maximum width for each column 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the total number of columns is dynamically changed if we find 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wider rows as we go through the children 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the array is reused for each layout operation; the array can grow 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // but never shrinks. Unused extra cells in the array are just ignored 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this behavior avoids to unnecessary grow the array after the first 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // layout operation 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View child = getChildAt(i); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child.getVisibility() == GONE) { 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child instanceof TableRow) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final TableRow row = (TableRow) child; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // forces the row's height 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewGroup.LayoutParams layoutParams = row.getLayoutParams(); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project layoutParams.height = LayoutParams.WRAP_CONTENT; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] widths = row.getColumnsWidths(widthMeasureSpec); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newLength = widths.length; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this is the first row, we just need to copy the values 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (firstRow) { 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMaxWidths == null || mMaxWidths.length != newLength) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaxWidths = new int[newLength]; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(widths, 0, mMaxWidths, 0, newLength); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstRow = false; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = mMaxWidths.length; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int difference = newLength - length; 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the current row is wider than the previous rows, so 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we just grow the array and copy the values 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (difference > 0) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] oldMaxWidths = mMaxWidths; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaxWidths = new int[newLength]; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(oldMaxWidths, 0, mMaxWidths, 0, 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldMaxWidths.length); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(widths, oldMaxWidths.length, 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaxWidths, oldMaxWidths.length, difference); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the row is narrower or of the same width as the previous 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // rows, so we find the maximum width for each column 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the row is narrower than the previous ones, 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // difference will be negative 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] maxWidths = mMaxWidths; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length = Math.min(length, newLength); 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j = 0; j < length; j++) { 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[j] = Math.max(maxWidths[j], widths[j]); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Shrinks the columns if their total width is greater than the 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * width allocated by widthMeasureSpec. When the total width is less 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * than the allocated width, this method attempts to stretch columns 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to fill the remaining space.</p> 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthMeasureSpec the width measure specification as indicated 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by this widget's parent 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void shrinkAndStretchColumns(int widthMeasureSpec) { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when we have no row, mMaxWidths is not initialized and the loop 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // below could cause a NPE 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMaxWidths == null) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // should we honor AT_MOST, EXACTLY and UNSPECIFIED? 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int totalWidth = 0; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int width : mMaxWidths) { 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalWidth += width; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight; 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((totalWidth > size) && (mShrinkAllColumns || mShrinkableColumns.size() > 0)) { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // oops, the largest columns are wider than the row itself 5636741c941a76d17c257c396d86c7561aa43005b1aGilles Debunne // fairly redistribute the row's width among the columns 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutateColumnsWidth(mShrinkableColumns, mShrinkAllColumns, size, totalWidth); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((totalWidth < size) && (mStretchAllColumns || mStretchableColumns.size() > 0)) { 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if we have some space left, we distribute it among the 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // expandable columns 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutateColumnsWidth(mStretchableColumns, mStretchAllColumns, size, totalWidth); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void mutateColumnsWidth(SparseBooleanArray columns, 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allColumns, int size, int totalWidth) { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int skipped = 0; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] maxWidths = mMaxWidths; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int length = maxWidths.length; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = allColumns ? length : columns.size(); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int totalExtraSpace = size - totalWidth; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int extraSpace = totalExtraSpace / count; 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 581f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne // Column's widths are changed: force child table rows to re-measure. 582f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne // (done by super.measureVertical after shrinkAndStretchColumns.) 583f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne final int nbChildren = getChildCount(); 584f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne for (int i = 0; i < nbChildren; i++) { 585f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne View child = getChildAt(i); 586f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne if (child instanceof TableRow) { 587f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne child.forceLayout(); 588f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne } 589f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne } 590f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allColumns) { 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int column = columns.keyAt(i); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (columns.valueAt(i)) { 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (column < length) { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[column] += extraSpace; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skipped++; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[i] += extraSpace; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we don't skip any column so we can return right away 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (skipped > 0 && skipped < count) { 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reclaim any extra space we left to columns that don't exist 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extraSpace = skipped * extraSpace / (count - skipped); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int column = columns.keyAt(i); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (columns.valueAt(i) && column < length) { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extraSpace > maxWidths[column]) { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[column] = 0; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[column] += extraSpace; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams generateLayoutParams(AttributeSet attrs) { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new TableLayout.LayoutParams(getContext(), attrs); 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a set of layout parameters with a width of 637980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}, 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and a height of {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}. 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected LinearLayout.LayoutParams generateDefaultLayoutParams() { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new LayoutParams(); 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return p instanceof TableLayout.LayoutParams; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected LinearLayout.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new LayoutParams(p); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This set of layout parameters enforces the width of each child to be 663980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link #MATCH_PARENT} and the height of each child to be 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #WRAP_CONTENT}, but only if the height is not specified.</p> 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings({"UnusedDeclaration"}) 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class LayoutParams extends LinearLayout.LayoutParams { 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(Context c, AttributeSet attrs) { 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(c, attrs); 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(int w, int h) { 679980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy super(MATCH_PARENT, h); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(int w, int h, float initWeight) { 686980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy super(MATCH_PARENT, h, initWeight); 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the child width to 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.view.ViewGroup.LayoutParams} and the child height to 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}.</p> 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams() { 695980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy super(MATCH_PARENT, WRAP_CONTENT); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(ViewGroup.LayoutParams p) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(p); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(MarginLayoutParams source) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(source); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Fixes the row's width to 714980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}; the row's 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * height is fixed to 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} if no layout 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * height is specified.</p> 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param a the styled attributes set 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthAttr the width attribute to fetch 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param heightAttr the height attribute to fetch 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void setBaseAttributes(TypedArray a, 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthAttr, int heightAttr) { 726980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy this.width = MATCH_PARENT; 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (a.hasValue(heightAttr)) { 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.height = a.getLayoutDimension(heightAttr, "layout_height"); 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.height = WRAP_CONTENT; 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>A pass-through listener acts upon the events and dispatches them 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to another listener. This allows the table layout to set its own internal 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hierarchy change listener without preventing the user to setup his.</p> 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class PassThroughHierarchyChangeListener implements 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OnHierarchyChangeListener { 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnHierarchyChangeListener mOnHierarchyChangeListener; 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onChildViewAdded(View parent, View child) { 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project trackCollapsedColumns(child); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnHierarchyChangeListener != null) { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnHierarchyChangeListener.onChildViewAdded(parent, child); 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onChildViewRemoved(View parent, View child) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnHierarchyChangeListener != null) { 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnHierarchyChangeListener.onChildViewRemoved(parent, child); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 765