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