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; 278a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 288a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.regex.Pattern; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>A layout that arranges its children into rows and columns. 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A TableLayout consists of a number of {@link android.widget.TableRow} objects, 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each defining a row (actually, you can have other children, which will be 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * explained below). TableLayout containers do not display border lines for 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * their rows, columns, or cells. Each row has zero or more cells; each cell can 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hold one {@link android.view.View View} object. The table has as many columns 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the row with the most cells. A table can leave cells empty. Cells can span 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * columns, as they can in HTML.</p> 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The width of a column is defined by the row with the widest cell in that 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * column. However, a TableLayout can specify certain columns as shrinkable or 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stretchable by calling 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setColumnShrinkable(int, boolean) setColumnShrinkable()} 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #setColumnStretchable(int, boolean) setColumnStretchable()}. If 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * marked as shrinkable, the column width can be shrunk to fit the table into 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * its parent object. If marked as stretchable, it can expand in width to fit 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * any extra space. The total width of the table is defined by its parent 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * container. It is important to remember that a column can be both shrinkable 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and stretchable. In such a situation, the column will change its size to 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * always use up the available space, but never more. Finally, you can hide a 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * column by calling 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setColumnCollapsed(int,boolean) setColumnCollapsed()}.</p> 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The children of a TableLayout cannot specify the <code>layout_width</code> 57980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * attribute. Width is always <code>MATCH_PARENT</code>. However, the 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>layout_height</code> attribute can be defined by a child; default value 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is {@link android.widget.TableLayout.LayoutParams#WRAP_CONTENT}. If the child 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is a {@link android.widget.TableRow}, then the height is always 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.widget.TableLayout.LayoutParams#WRAP_CONTENT}.</p> 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> Cells must be added to a row in increasing column order, both in code and 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * XML. Column numbers are zero-based. If you don't specify a column number for 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a child cell, it will autoincrement to the next available column. If you skip 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a column number, it will be considered an empty cell in that row. See the 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * TableLayout examples in ApiDemos for examples of creating tables in XML.</p> 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Although the typical child of a TableLayout is a TableRow, you can 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * actually use any View subclass as a direct child of TableLayout. The View 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will be displayed as a single row that spans all the table columns.</p> 7241ec65355bd6ded652769725b276d47c54a0d913Scott Main * 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 187c3c0e39ab53a27d4fc92a8a3be15d1c1ce850d70Adam Powell // TableLayouts are always in vertical orientation; keep this tracked 188c3c0e39ab53a27d4fc92a8a3be15d1c1ce850d70Adam Powell // for shared LinearLayout code. 189c3c0e39ab53a27d4fc92a8a3be15d1c1ce850d70Adam Powell setOrientation(VERTICAL); 190c3c0e39ab53a27d4fc92a8a3be15d1c1ce850d70Adam Powell 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPassThroughListener = new PassThroughHierarchyChangeListener(); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure to call the parent class method to avoid potential 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // infinite loops 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setOnHierarchyChangeListener(mPassThroughListener); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInitialized = true; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setOnHierarchyChangeListener( 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OnHierarchyChangeListener listener) { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the user listener is delegated to our pass-through listener 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPassThroughListener.mOnHierarchyChangeListener = listener; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void requestRowsLayout() { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInitialized) { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getChildAt(i).requestLayout(); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestLayout() { 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInitialized) { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = getChildCount(); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getChildAt(i).forceLayout(); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.requestLayout(); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether all columns are shrinkable or not.</p> 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if all columns are shrinkable, false otherwise 2371018fb42cb4958511a141787705aa429c5ec9bd3Philip Milne * 2381018fb42cb4958511a141787705aa429c5ec9bd3Philip Milne * @attr ref android.R.styleable#TableLayout_shrinkColumns 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShrinkAllColumns() { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mShrinkAllColumns; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Convenience method to mark all columns as shrinkable.</p> 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param shrinkAllColumns true to mark all columns shrinkable 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_shrinkColumns 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setShrinkAllColumns(boolean shrinkAllColumns) { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShrinkAllColumns = shrinkAllColumns; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Indicates whether all columns are stretchable or not.</p> 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if all columns are stretchable, false otherwise 2591018fb42cb4958511a141787705aa429c5ec9bd3Philip Milne * 2601018fb42cb4958511a141787705aa429c5ec9bd3Philip Milne * @attr ref android.R.styleable#TableLayout_stretchColumns 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isStretchAllColumns() { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStretchAllColumns; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Convenience method to mark all columns as stretchable.</p> 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param stretchAllColumns true to mark all columns stretchable 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_stretchColumns 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setStretchAllColumns(boolean stretchAllColumns) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStretchAllColumns = stretchAllColumns; 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Collapses or restores a given column. When collapsed, a column 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * does not appear on screen and the extra space is reclaimed by the 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * other columns. A column is collapsed/restored only when it belongs to 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a {@link android.widget.TableRow}.</p> 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Calling this method requests a layout operation.</p> 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isCollapsed true if the column must be collapsed, false otherwise 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_collapseColumns 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColumnCollapsed(int columnIndex, boolean isCollapsed) { 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // update the collapse status of the column 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCollapsedColumns.put(columnIndex, isCollapsed); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = getChildCount(); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View view = getChildAt(i); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (view instanceof TableRow) { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((TableRow) view).setColumnCollapsed(columnIndex, isCollapsed); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns the collapsed state of the specified column.</p> 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the column is collapsed, false otherwise 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isColumnCollapsed(int columnIndex) { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mCollapsedColumns.get(columnIndex); 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Makes the given column stretchable or not. When stretchable, a column 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * takes up as much as available space as possible in its row.</p> 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Calling this method requests a layout operation.</p> 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isStretchable true if the column must be stretchable, 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * false otherwise. Default is false. 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_stretchColumns 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColumnStretchable(int columnIndex, boolean isStretchable) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStretchableColumns.put(columnIndex, isStretchable); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns whether the specified column is stretchable or not.</p> 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the column is stretchable, false otherwise 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isColumnStretchable(int columnIndex) { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStretchAllColumns || mStretchableColumns.get(columnIndex); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Makes the given column shrinkable or not. When a row is too wide, the 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * table can reclaim extra space from shrinkable columns.</p> 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Calling this method requests a layout operation.</p> 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param isShrinkable true if the column must be shrinkable, 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * false otherwise. Default is false. 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#TableLayout_shrinkColumns 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColumnShrinkable(int columnIndex, boolean isShrinkable) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShrinkableColumns.put(columnIndex, isShrinkable); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Returns whether the specified column is shrinkable or not.</p> 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnIndex the index of the column 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return true if the column is shrinkable, false otherwise. Default is false. 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isColumnShrinkable(int columnIndex) { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mShrinkAllColumns || mShrinkableColumns.get(columnIndex); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Applies the columns collapse status to a new row added to this 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * table. This method is invoked by PassThroughHierarchyChangeListener 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * upon child insertion.</p> 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This method only applies to {@link android.widget.TableRow} 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instances.</p> 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param child the newly added child 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void trackCollapsedColumns(View child) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child instanceof TableRow) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final TableRow row = (TableRow) child; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SparseBooleanArray collapsedColumns = mCollapsedColumns; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = collapsedColumns.size(); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int columnIndex = collapsedColumns.keyAt(i); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isCollapsed = collapsedColumns.valueAt(i); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the collapse status is set only when the column should be 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // collapsed; otherwise, this might affect the default 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // visibility of the row's children 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isCollapsed) { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row.setColumnCollapsed(columnIndex, isCollapsed); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View child) { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.addView(child); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View child, int index) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.addView(child, index); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View child, ViewGroup.LayoutParams params) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.addView(child, params); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addView(View child, int index, ViewGroup.LayoutParams params) { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.addView(child, index, params); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestRowsLayout(); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // enforce vertical layout 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project measureVertical(widthMeasureSpec, heightMeasureSpec); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onLayout(boolean changed, int l, int t, int r, int b) { 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // enforce vertical layout 448ad365cc217c989c3b688ae839d6f94ee8889a84ePhilip Milne layoutVertical(l, t, r, b); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void measureChildBeforeLayout(View child, int childIndex, 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthMeasureSpec, int totalWidth, 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int heightMeasureSpec, int totalHeight) { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when the measured child is a table row, we force the width of its 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // children with the widths computed in findLargestCells() 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child instanceof TableRow) { 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((TableRow) child).setColumnsWidthConstraints(mMaxWidths); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.measureChildBeforeLayout(child, childIndex, 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthMeasureSpec, totalWidth, heightMeasureSpec, totalHeight); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void measureVertical(int widthMeasureSpec, int heightMeasureSpec) { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project findLargestCells(widthMeasureSpec); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shrinkAndStretchColumns(widthMeasureSpec); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.measureVertical(widthMeasureSpec, heightMeasureSpec); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Finds the largest cell in each column. For each column, the width of 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the largest cell is applied to all the other cells.</p> 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthMeasureSpec the measure constraint imposed by our parent 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void findLargestCells(int widthMeasureSpec) { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean firstRow = true; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // find the maximum width for each column 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the total number of columns is dynamically changed if we find 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wider rows as we go through the children 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the array is reused for each layout operation; the array can grow 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // but never shrinks. Unused extra cells in the array are just ignored 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this behavior avoids to unnecessary grow the array after the first 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // layout operation 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View child = getChildAt(i); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child.getVisibility() == GONE) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child instanceof TableRow) { 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final TableRow row = (TableRow) child; 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // forces the row's height 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewGroup.LayoutParams layoutParams = row.getLayoutParams(); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project layoutParams.height = LayoutParams.WRAP_CONTENT; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] widths = row.getColumnsWidths(widthMeasureSpec); 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int newLength = widths.length; 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this is the first row, we just need to copy the values 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (firstRow) { 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMaxWidths == null || mMaxWidths.length != newLength) { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaxWidths = new int[newLength]; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(widths, 0, mMaxWidths, 0, newLength); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstRow = false; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int length = mMaxWidths.length; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int difference = newLength - length; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the current row is wider than the previous rows, so 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we just grow the array and copy the values 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (difference > 0) { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] oldMaxWidths = mMaxWidths; 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaxWidths = new int[newLength]; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(oldMaxWidths, 0, mMaxWidths, 0, 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldMaxWidths.length); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(widths, oldMaxWidths.length, 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMaxWidths, oldMaxWidths.length, difference); 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the row is narrower or of the same width as the previous 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // rows, so we find the maximum width for each column 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the row is narrower than the previous ones, 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // difference will be negative 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] maxWidths = mMaxWidths; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project length = Math.min(length, newLength); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j = 0; j < length; j++) { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[j] = Math.max(maxWidths[j], widths[j]); 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 } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Shrinks the columns if their total width is greater than the 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * width allocated by widthMeasureSpec. When the total width is less 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * than the allocated width, this method attempts to stretch columns 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to fill the remaining space.</p> 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthMeasureSpec the width measure specification as indicated 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by this widget's parent 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void shrinkAndStretchColumns(int widthMeasureSpec) { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when we have no row, mMaxWidths is not initialized and the loop 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // below could cause a NPE 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMaxWidths == null) { 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // should we honor AT_MOST, EXACTLY and UNSPECIFIED? 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int totalWidth = 0; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int width : mMaxWidths) { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project totalWidth += width; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = MeasureSpec.getSize(widthMeasureSpec) - mPaddingLeft - mPaddingRight; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((totalWidth > size) && (mShrinkAllColumns || mShrinkableColumns.size() > 0)) { 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // oops, the largest columns are wider than the row itself 5716741c941a76d17c257c396d86c7561aa43005b1aGilles Debunne // fairly redistribute the row's width among the columns 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutateColumnsWidth(mShrinkableColumns, mShrinkAllColumns, size, totalWidth); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if ((totalWidth < size) && (mStretchAllColumns || mStretchableColumns.size() > 0)) { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if we have some space left, we distribute it among the 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // expandable columns 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutateColumnsWidth(mStretchableColumns, mStretchAllColumns, size, totalWidth); 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void mutateColumnsWidth(SparseBooleanArray columns, 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allColumns, int size, int totalWidth) { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int skipped = 0; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int[] maxWidths = mMaxWidths; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int length = maxWidths.length; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = allColumns ? length : columns.size(); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int totalExtraSpace = size - totalWidth; 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int extraSpace = totalExtraSpace / count; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne // Column's widths are changed: force child table rows to re-measure. 590f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne // (done by super.measureVertical after shrinkAndStretchColumns.) 591f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne final int nbChildren = getChildCount(); 592f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne for (int i = 0; i < nbChildren; i++) { 593f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne View child = getChildAt(i); 594f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne if (child instanceof TableRow) { 595f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne child.forceLayout(); 596f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne } 597f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne } 598f5c6eff63d19a9f7a970a4f90619edac873c006dGilles Debunne 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allColumns) { 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int column = columns.keyAt(i); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (columns.valueAt(i)) { 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (column < length) { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[column] += extraSpace; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skipped++; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[i] += extraSpace; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we don't skip any column so we can return right away 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (skipped > 0 && skipped < count) { 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reclaim any extra space we left to columns that don't exist 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extraSpace = skipped * extraSpace / (count - skipped); 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i++) { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int column = columns.keyAt(i); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (columns.valueAt(i) && column < length) { 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extraSpace > maxWidths[column]) { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[column] = 0; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project maxWidths[column] += extraSpace; 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 } 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams generateLayoutParams(AttributeSet attrs) { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new TableLayout.LayoutParams(getContext(), attrs); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns a set of layout parameters with a width of 645980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}, 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and a height of {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}. 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected LinearLayout.LayoutParams generateDefaultLayoutParams() { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new 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 boolean checkLayoutParams(ViewGroup.LayoutParams p) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return p instanceof TableLayout.LayoutParams; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected LinearLayout.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new LayoutParams(p); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6698a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 6708a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 6718a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityEvent(event); 6728a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov event.setClassName(TableLayout.class.getName()); 6738a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 6748a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 6758a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 6768a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 6778a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityNodeInfo(info); 6788a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov info.setClassName(TableLayout.class.getName()); 6798a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 6808a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This set of layout parameters enforces the width of each child to be 683980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link #MATCH_PARENT} and the height of each child to be 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #WRAP_CONTENT}, but only if the height is not specified.</p> 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings({"UnusedDeclaration"}) 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class LayoutParams extends LinearLayout.LayoutParams { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(Context c, AttributeSet attrs) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(c, attrs); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(int w, int h) { 699980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy super(MATCH_PARENT, h); 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(int w, int h, float initWeight) { 706980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy super(MATCH_PARENT, h, initWeight); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sets the child width to 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.view.ViewGroup.LayoutParams} and the child height to 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}.</p> 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams() { 715980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy super(MATCH_PARENT, WRAP_CONTENT); 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(ViewGroup.LayoutParams p) { 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(p); 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LayoutParams(MarginLayoutParams source) { 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(source); 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Fixes the row's width to 734980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy * {@link android.view.ViewGroup.LayoutParams#MATCH_PARENT}; the row's 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * height is fixed to 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT} if no layout 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * height is specified.</p> 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param a the styled attributes set 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param widthAttr the width attribute to fetch 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param heightAttr the height attribute to fetch 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 744579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke protected void setBaseAttributes(TypedArray a, 745579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke int widthAttr, int heightAttr) { 746980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy this.width = MATCH_PARENT; 747579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke if (a.hasValue(heightAttr)) { 748579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke this.height = a.getLayoutDimension(heightAttr, "layout_height"); 749579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke } else { 750579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke this.height = WRAP_CONTENT; 751579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke } 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 * <p>A pass-through listener acts upon the events and dispatches them 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to another listener. This allows the table layout to set its own internal 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hierarchy change listener without preventing the user to setup his.</p> 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class PassThroughHierarchyChangeListener implements 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project OnHierarchyChangeListener { 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private OnHierarchyChangeListener mOnHierarchyChangeListener; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onChildViewAdded(View parent, View child) { 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project trackCollapsedColumns(child); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnHierarchyChangeListener != null) { 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnHierarchyChangeListener.onChildViewAdded(parent, child); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onChildViewRemoved(View parent, View child) { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mOnHierarchyChangeListener != null) { 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOnHierarchyChangeListener.onChildViewRemoved(parent, child); 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 785