GridView.java revision aebd28f729fa28016d70551d0372ab7fcd56ee1a
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 android.content.Context; 20499cb9f516062b654952d282f211bee44c31a3c2Winson Chungimport android.content.Intent; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Gravity; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 26499cb9f516062b654952d282f211bee44c31a3c2Winson Chungimport android.view.SoundEffectConstants; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 288d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sappersteinimport android.view.ViewDebug; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup; 308a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityEvent; 318a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganovimport android.view.accessibility.AccessibilityNodeInfo; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.animation.GridLayoutAnimationController; 33499cb9f516062b654952d282f211bee44c31a3c2Winson Chungimport android.widget.RemoteViews.RemoteView; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A view that shows items in two-dimensional scrolling grid. The items in the 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * grid come from the {@link ListAdapter} associated with this view. 3941ec65355bd6ded652769725b276d47c54a0d913Scott Main * 4041ec65355bd6ded652769725b276d47c54a0d913Scott Main * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-gridview.html">Grid 4141ec65355bd6ded652769725b276d47c54a0d913Scott Main * View tutorial</a>.</p> 4284c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * 4384c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @attr ref android.R.styleable#GridView_horizontalSpacing 4484c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @attr ref android.R.styleable#GridView_verticalSpacing 4584c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @attr ref android.R.styleable#GridView_stretchMode 4684c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @attr ref android.R.styleable#GridView_columnWidth 4784c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @attr ref android.R.styleable#GridView_numColumns 4884c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @attr ref android.R.styleable#GridView_gravity 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 50499cb9f516062b654952d282f211bee44c31a3c2Winson Chung@RemoteView 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class GridView extends AbsListView { 5284c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy /** 5384c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * Disables stretching. 5484c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * 5584c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @see #setStretchMode(int) 5684c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy */ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int NO_STRETCH = 0; 5884c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy /** 5984c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * Stretches the spacing between columns. 6084c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * 6184c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @see #setStretchMode(int) 6284c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy */ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STRETCH_SPACING = 1; 6484c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy /** 6584c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * Stretches columns. 6684c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * 6784c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @see #setStretchMode(int) 6884c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STRETCH_COLUMN_WIDTH = 2; 7084c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy /** 7184c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * Stretches the spacing between columns. The spacing is uniform. 7284c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * 7384c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @see #setStretchMode(int) 7484c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy */ 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STRETCH_SPACING_UNIFORM = 3; 7684c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy 7784c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy /** 7884c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * Creates as many columns as can fit on screen. 7984c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * 8084c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy * @see #setNumColumns(int) 8184c6b95a7776ea5924a7c3e5a511c4df5c75924dRomain Guy */ 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int AUTO_FIT = -1; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNumColumns = AUTO_FIT; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mHorizontalSpacing = 0; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRequestedHorizontalSpacing; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mVerticalSpacing = 0; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mStretchMode = STRETCH_COLUMN_WIDTH; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mColumnWidth; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRequestedColumnWidth; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mRequestedNumColumns; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mReferenceView = null; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View mReferenceViewInSelectedRow = null; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mGravity = Gravity.LEFT; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Rect mTempRect = new Rect(); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GridView(Context context) { 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GridView(Context context, AttributeSet attrs) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, attrs, com.android.internal.R.attr.gridViewStyle); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GridView(Context context, AttributeSet attrs, int defStyle) { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(context, attrs, defStyle); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = context.obtainStyledAttributes(attrs, 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.GridView, defStyle, 0); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int hSpacing = a.getDimensionPixelOffset( 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.GridView_horizontalSpacing, 0); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setHorizontalSpacing(hSpacing); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int vSpacing = a.getDimensionPixelOffset( 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.GridView_verticalSpacing, 0); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setVerticalSpacing(vSpacing); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = a.getInt(com.android.internal.R.styleable.GridView_stretchMode, STRETCH_COLUMN_WIDTH); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setStretchMode(index); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int columnWidth = a.getDimensionPixelOffset(com.android.internal.R.styleable.GridView_columnWidth, -1); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (columnWidth > 0) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setColumnWidth(columnWidth); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numColumns = a.getInt(com.android.internal.R.styleable.GridView_numColumns, 1); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNumColumns(numColumns); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = a.getInt(com.android.internal.R.styleable.GridView_gravity, -1); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0) { 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setGravity(index); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ListAdapter getAdapter() { 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAdapter; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 150499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * Sets up this AbsListView to use a remote views adapter which connects to a RemoteViewsService 151499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * through the specified intent. 152499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * @param intent the intent used to identify the RemoteViewsService for the adapter to connect to. 153499cb9f516062b654952d282f211bee44c31a3c2Winson Chung */ 154499cb9f516062b654952d282f211bee44c31a3c2Winson Chung @android.view.RemotableViewMethod 155499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public void setRemoteViewsAdapter(Intent intent) { 156499cb9f516062b654952d282f211bee44c31a3c2Winson Chung super.setRemoteViewsAdapter(intent); 157499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 158499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 159499cb9f516062b654952d282f211bee44c31a3c2Winson Chung /** 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the data behind this GridView. 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param adapter the adapter providing the grid's data 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setAdapter(ListAdapter adapter) { 166df36b0579e1e550de3d66a20362717e49b23235cRomain Guy if (mAdapter != null && mDataSetObserver != null) { 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdapter.unregisterDataSetObserver(mDataSetObserver); 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resetList(); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecycler.clear(); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdapter = adapter; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOldSelectedPosition = INVALID_POSITION; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOldSelectedRowId = INVALID_ROW_ID; 176f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell 177f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell // AbsListView#setAdapter will update choice mode states. 178f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell super.setAdapter(adapter); 179f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdapter != null) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOldItemCount = mItemCount; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mItemCount = mAdapter.getCount(); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataChanged = true; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataSetObserver = new AdapterDataSetObserver(); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAdapter.registerDataSetObserver(mDataSetObserver); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecycler.setViewTypeCount(mAdapter.getViewTypeCount()); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStackFromBottom) { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position = lookForSelectablePosition(mItemCount - 1, false); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position = lookForSelectablePosition(0, true); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectedPositionInt(position); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNextSelectedPositionInt(position); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkSelectionChanged(); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Nothing selected 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkSelectionChanged(); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int lookForSelectablePosition(int position, boolean lookDown) { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ListAdapter adapter = mAdapter; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (adapter == null || isInTouchMode()) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return INVALID_POSITION; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (position < 0 || position >= mItemCount) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return INVALID_POSITION; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return position; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@inheritDoc} 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void fillGap(boolean down) { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (down) { 2338c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell int paddingTop = 0; 2348c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { 2358c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell paddingTop = getListPaddingTop(); 2368c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int startOffset = count > 0 ? 2388c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell getChildAt(count - 1).getBottom() + verticalSpacing : paddingTop; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = mFirstPosition + count; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStackFromBottom) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position += numColumns - 1; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(position, startOffset); 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project correctTooHigh(numColumns, verticalSpacing, getChildCount()); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2468c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell int paddingBottom = 0; 2478c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { 2488c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell paddingBottom = getListPaddingBottom(); 2498c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int startOffset = count > 0 ? 2518c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell getChildAt(0).getTop() - verticalSpacing : getHeight() - paddingBottom; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int position = mFirstPosition; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position -= numColumns; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project position--; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(position, startOffset); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project correctTooLow(numColumns, verticalSpacing, getChildCount()); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the list from pos down to the end of the list view. 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pos The first position to put in the list 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param nextTop The location where the top of the item associated with pos 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should be drawn 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that is currently selected, if it happens to be in the 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * range that we draw. 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillDown(int pos, int nextTop) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View selectedView = null; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2778c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell int end = (mBottom - mTop); 2788c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { 2798c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell end -= mListPadding.bottom; 2808c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (nextTop < end && pos < mItemCount) { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View temp = makeRow(pos, nextTop, true); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp != null) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedView = temp; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2888bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy // mReferenceView will change with each call to makeRow() 2898bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy // do not cache in a local variable outside of this loop 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextTop = mReferenceView.getBottom() + mVerticalSpacing; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos += mNumColumns; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 295b967392e0170af8cfd8053fd43fcdf8c46f703e9Adam Cohen setVisibleRangeHint(mFirstPosition, mFirstPosition + getChildCount() - 1); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return selectedView; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View makeRow(int startPos, int y, boolean flow) { 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int columnWidth = mColumnWidth; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int horizontalSpacing = mHorizontalSpacing; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int last; 3048bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy int nextLeft = mListPadding.left + 3058bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy ((mStretchMode == STRETCH_SPACING_UNIFORM) ? horizontalSpacing : 0); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project last = Math.min(startPos + mNumColumns, mItemCount); 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project last = startPos + 1; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startPos = Math.max(0, startPos - mNumColumns + 1); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (last - startPos < mNumColumns) { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextLeft += (mNumColumns - (last - startPos)) * (columnWidth + horizontalSpacing); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View selectedView = null; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean hasFocus = shouldShowSelector(); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean inClick = touchModeDrawsInPressedState(); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = mSelectedPosition; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3248bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy View child = null; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int pos = startPos; pos < last; pos++) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // is this the selected item? 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean selected = pos == selectedPosition; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // does the list view have focus or contain focus 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int where = flow ? -1 : pos - startPos; 3318bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy child = makeAndAddView(pos, y, flow, nextLeft, selected, where); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextLeft += columnWidth; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pos < last - 1) { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextLeft += horizontalSpacing; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selected && (hasFocus || inClick)) { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedView = child; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3438bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy mReferenceView = child; 3448bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selectedView != null) { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReferenceViewInSelectedRow = mReferenceView; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return selectedView; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the list from pos up to the top of the list view. 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param pos The first position to put in the list 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param nextBottom The location where the bottom of the item associated 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with pos should be drawn 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that is currently selected 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillUp(int pos, int nextBottom) { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View selectedView = null; 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3658c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell int end = 0; 3668c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell if ((mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { 3678c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell end = mListPadding.top; 3688c3e0fc84f69e9fe704dc20dd6c2bab1ce43fe93Adam Powell } 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (nextBottom > end && pos >= 0) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View temp = makeRow(pos, nextBottom, false); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp != null) { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project selectedView = temp; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nextBottom = mReferenceView.getTop() - mVerticalSpacing; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = pos; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos -= mNumColumns; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStackFromBottom) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = Math.max(0, pos + 1); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 388b967392e0170af8cfd8053fd43fcdf8c46f703e9Adam Cohen setVisibleRangeHint(mFirstPosition, mFirstPosition + getChildCount() - 1); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return selectedView; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the list from top to bottom, starting with mFirstPosition 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param nextTop The location where the top of the first item should be 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * drawn 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that is currently selected 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillFromTop(int nextTop) { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = Math.min(mFirstPosition, mSelectedPosition); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = Math.min(mFirstPosition, mItemCount - 1); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition < 0) { 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = 0; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition -= mFirstPosition % mNumColumns; 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fillDown(mFirstPosition, nextTop); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillFromBottom(int lastPosition, int nextBottom) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastPosition = Math.max(lastPosition, mSelectedPosition); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastPosition = Math.min(lastPosition, mItemCount - 1); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedPosition = mItemCount - 1 - lastPosition; 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastPosition = mItemCount - 1 - (invertedPosition - (invertedPosition % mNumColumns)); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fillUp(lastPosition, nextBottom); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillSelection(int childrenTop, int childrenBottom) { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = reconcileSelectedPosition(); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowStart; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowEnd = -1; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = selectedPosition - (selectedPosition % numColumns); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedSelection = mItemCount - 1 - selectedPosition; 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = Math.max(0, rowEnd - numColumns + 1); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int fadingEdgeLength = getVerticalFadingEdgeLength(); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int topSelectionPixel = getTopSelectionPixel(childrenTop, fadingEdgeLength, rowStart); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View sel = makeRow(mStackFromBottom ? rowEnd : rowStart, topSelectionPixel, true); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = rowStart; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View referenceView = mReferenceView; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowStart + numColumns, referenceView.getBottom() + verticalSpacing); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pinToBottom(childrenBottom); 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - numColumns, referenceView.getTop() - verticalSpacing); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int bottomSelectionPixel = getBottomSelectionPixel(childrenBottom, 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fadingEdgeLength, numColumns, rowStart); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = bottomSelectionPixel - referenceView.getBottom(); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(offset); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - 1, referenceView.getTop() - verticalSpacing); 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pinToTop(childrenTop); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowEnd + numColumns, referenceView.getBottom() + verticalSpacing); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sel; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void pinToTop(int childrenTop) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition == 0) { 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int top = getChildAt(0).getTop(); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = childrenTop - top; 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset < 0) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(offset); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void pinToBottom(int childrenBottom) { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition + count == mItemCount) { 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int bottom = getChildAt(count - 1).getBottom(); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int offset = childrenBottom - bottom; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset > 0) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(offset); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int findMotionRow(int y) { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount > 0) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < childCount; i += numColumns) { 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y <= getChildAt(i).getBottom()) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFirstPosition + i; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = childCount - 1; i >= 0; i -= numColumns) { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (y >= getChildAt(i).getTop()) { 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFirstPosition + i; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return INVALID_POSITION; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Layout during a scroll that results from tracking motion events. Places 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the mMotionPosition view at the offset specified by mMotionViewTop, and 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * then build surrounding views from there. 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position the position at which to start filling 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param top the top of the view at that position 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The selected view, or null if the selected view is outside the 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * visible area. 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillSpecific(int position, int top) { 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int motionRowStart; 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int motionRowEnd = -1; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project motionRowStart = position - (position % numColumns); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedSelection = mItemCount - 1 - position; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project motionRowEnd = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project motionRowStart = Math.max(0, motionRowEnd - numColumns + 1); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View temp = makeRow(mStackFromBottom ? motionRowEnd : motionRowStart, top, true); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Possibly changed again in fillUp if we add rows above this one. 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = motionRowStart; 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View referenceView = mReferenceView; 5398bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy // We didn't have anything to layout, bail out 5408bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy if (referenceView == null) { 5418bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy return null; 5428bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy } 5438bcdc0764f2f569173863655f96cdec2aea2d0daRomain Guy 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View above; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View below; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project above = fillUp(motionRowStart - numColumns, referenceView.getTop() - verticalSpacing); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project below = fillDown(motionRowStart + numColumns, referenceView.getBottom() + verticalSpacing); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if we have dragged the bottom of the grid too high 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount > 0) { 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project correctTooHigh(numColumns, verticalSpacing, childCount); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project below = fillDown(motionRowEnd + numColumns, referenceView.getBottom() + verticalSpacing); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project above = fillUp(motionRowStart - 1, referenceView.getTop() - verticalSpacing); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if we have dragged the bottom of the grid too high 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount > 0) { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project correctTooLow(numColumns, verticalSpacing, childCount); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (temp != null) { 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return temp; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (above != null) { 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return above; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return below; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void correctTooHigh(int numColumns, int verticalSpacing, int childCount) { 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // First see if the last item is visible 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int lastPosition = mFirstPosition + childCount - 1; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastPosition == mItemCount - 1 && childCount > 0) { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the last child ... 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View lastChild = getChildAt(childCount - 1); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ... and its bottom edge 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int lastBottom = lastChild.getBottom(); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is bottom of our drawable area 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int end = (mBottom - mTop) - mListPadding.bottom; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is how far the bottom edge of the last view is from the bottom of the 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // drawable area 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bottomOffset = end - lastBottom; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View firstChild = getChildAt(0); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int firstTop = firstChild.getTop(); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure we are 1) Too high, and 2) Either there are more rows above the 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // first row or the first row is scrolled off the top of the drawable area 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (bottomOffset > 0 && (mFirstPosition > 0 || firstTop < mListPadding.top)) { 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition == 0) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't pull the top too far down 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottomOffset = Math.min(bottomOffset, mListPadding.top - firstTop); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Move everything down 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(bottomOffset); 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition > 0) { 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fill the gap that was opened above mFirstPosition with more rows, if 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // possible 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(mFirstPosition - (mStackFromBottom ? 1 : numColumns), 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project firstChild.getTop() - verticalSpacing); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Close up the remaining gap 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void correctTooLow(int numColumns, int verticalSpacing, int childCount) { 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition == 0 && childCount > 0) { 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Get the first child ... 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View firstChild = getChildAt(0); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ... and its top edge 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int firstTop = firstChild.getTop(); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is top of our drawable area 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int start = mListPadding.top; 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is bottom of our drawable area 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int end = (mBottom - mTop) - mListPadding.bottom; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is how far the top edge of the first view is from the top of the 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // drawable area 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topOffset = firstTop - start; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View lastChild = getChildAt(childCount - 1); 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int lastBottom = lastChild.getBottom(); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int lastPosition = mFirstPosition + childCount - 1; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure we are 1) Too low, and 2) Either there are more rows below the 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // last row or the last row is scrolled off the bottom of the drawable area 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (topOffset > 0 && (lastPosition < mItemCount - 1 || lastBottom > end)) { 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastPosition == mItemCount - 1 ) { 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't pull the bottom too far up 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project topOffset = Math.min(topOffset, lastBottom - end); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Move everything up 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(-topOffset); 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastPosition < mItemCount - 1) { 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fill the gap that was opened below the last position with more rows, if 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // possible 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(lastPosition + (!mStackFromBottom ? 1 : numColumns), 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lastChild.getBottom() + verticalSpacing); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Close up the remaining gap 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the grid based on positioning the new selection at a specific 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location. The selection may be moved so that it does not intersect the 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * faded edges. The grid is then filled upwards and downwards from there. 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selectedTop Where the selected item should be 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenTop Where to start drawing children 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenBottom Last pixel where children can be drawn 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that currently has selection 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View fillFromSelection(int selectedTop, int childrenTop, int childrenBottom) { 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int fadingEdgeLength = getVerticalFadingEdgeLength(); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = mSelectedPosition; 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowStart; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowEnd = -1; 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = selectedPosition - (selectedPosition % numColumns); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int invertedSelection = mItemCount - 1 - selectedPosition; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = Math.max(0, rowEnd - numColumns + 1); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View sel; 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View referenceView; 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topSelectionPixel = getTopSelectionPixel(childrenTop, fadingEdgeLength, rowStart); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bottomSelectionPixel = getBottomSelectionPixel(childrenBottom, fadingEdgeLength, 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project numColumns, rowStart); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = makeRow(mStackFromBottom ? rowEnd : rowStart, selectedTop, true); 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Possibly changed again in fillUp if we add rows above this one. 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = rowStart; 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenceView = mReferenceView; 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustForTopFadingEdge(referenceView, topSelectionPixel, bottomSelectionPixel); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustForBottomFadingEdge(referenceView, topSelectionPixel, bottomSelectionPixel); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - numColumns, referenceView.getTop() - verticalSpacing); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowStart + numColumns, referenceView.getBottom() + verticalSpacing); 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowEnd + numColumns, referenceView.getBottom() + verticalSpacing); 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - 1, referenceView.getTop() - verticalSpacing); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sel; 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Calculate the bottom-most pixel we can draw the selection into 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenBottom Bottom pixel were children can be drawn 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fadingEdgeLength Length of the fading edge in pixels, if present 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param numColumns Number of columns in the grid 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rowStart The start of the row that will contain the selection 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The bottom-most pixel we can draw the selection into 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getBottomSelectionPixel(int childrenBottom, int fadingEdgeLength, 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int numColumns, int rowStart) { 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Last pixel we can draw the selection into 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bottomSelectionPixel = childrenBottom; 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rowStart + numColumns - 1 < mItemCount - 1) { 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bottomSelectionPixel -= fadingEdgeLength; 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bottomSelectionPixel; 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Calculate the top-most pixel we can draw the selection into 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenTop Top pixel were children can be drawn 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fadingEdgeLength Length of the fading edge in pixels, if present 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rowStart The start of the row that will contain the selection 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The top-most pixel we can draw the selection into 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getTopSelectionPixel(int childrenTop, int fadingEdgeLength, int rowStart) { 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // first pixel we can draw the selection into 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topSelectionPixel = childrenTop; 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rowStart > 0) { 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project topSelectionPixel += fadingEdgeLength; 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return topSelectionPixel; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Move all views upwards so the selected row does not interesect the bottom 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fading edge (if necessary). 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childInSelectedRow A child in the row that contains the selection 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param topSelectionPixel The topmost pixel we can draw the selection into 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bottomSelectionPixel The bottommost pixel we can draw the 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection into 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void adjustForBottomFadingEdge(View childInSelectedRow, 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topSelectionPixel, int bottomSelectionPixel) { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Some of the newly selected item extends below the bottom of the 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // list 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childInSelectedRow.getBottom() > bottomSelectionPixel) { 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Find space available above the selection into which we can 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // scroll upwards 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceAbove = childInSelectedRow.getTop() - topSelectionPixel; 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Find space required to bring the bottom of the selected item 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fully into view 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceBelow = childInSelectedRow.getBottom() - bottomSelectionPixel; 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offset = Math.min(spaceAbove, spaceBelow); 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now offset the selected item to get it into view 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(-offset); 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Move all views upwards so the selected row does not interesect the top 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fading edge (if necessary). 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childInSelectedRow A child in the row that contains the selection 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param topSelectionPixel The topmost pixel we can draw the selection into 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bottomSelectionPixel The bottommost pixel we can draw the 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection into 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void adjustForTopFadingEdge(View childInSelectedRow, 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int topSelectionPixel, int bottomSelectionPixel) { 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Some of the newly selected item extends above the top of the list 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childInSelectedRow.getTop() < topSelectionPixel) { 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Find space required to bring the top of the selected item 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fully into view 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceAbove = topSelectionPixel - childInSelectedRow.getTop(); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Find space available below the selection into which we can 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // scroll downwards 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceBelow = bottomSelectionPixel - childInSelectedRow.getBottom(); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offset = Math.min(spaceAbove, spaceBelow); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now offset the selected item to get it into view 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(offset); 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 812499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * Smoothly scroll to the specified adapter position. The view will 813499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * scroll such that the indicated position is displayed. 814499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * @param position Scroll to this adapter position. 815499cb9f516062b654952d282f211bee44c31a3c2Winson Chung */ 816499cb9f516062b654952d282f211bee44c31a3c2Winson Chung @android.view.RemotableViewMethod 817499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public void smoothScrollToPosition(int position) { 818499cb9f516062b654952d282f211bee44c31a3c2Winson Chung super.smoothScrollToPosition(position); 819499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 820499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 821499cb9f516062b654952d282f211bee44c31a3c2Winson Chung /** 822499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * Smoothly scroll to the specified adapter position offset. The view will 823499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * scroll such that the indicated position is displayed. 824499cb9f516062b654952d282f211bee44c31a3c2Winson Chung * @param offset The amount to offset from the adapter position to scroll to. 825499cb9f516062b654952d282f211bee44c31a3c2Winson Chung */ 826499cb9f516062b654952d282f211bee44c31a3c2Winson Chung @android.view.RemotableViewMethod 827499cb9f516062b654952d282f211bee44c31a3c2Winson Chung public void smoothScrollByOffset(int offset) { 828499cb9f516062b654952d282f211bee44c31a3c2Winson Chung super.smoothScrollByOffset(offset); 829499cb9f516062b654952d282f211bee44c31a3c2Winson Chung } 830499cb9f516062b654952d282f211bee44c31a3c2Winson Chung 831499cb9f516062b654952d282f211bee44c31a3c2Winson Chung /** 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Fills the grid based on positioning the new selection relative to the old 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection. The new selection will be placed at, above, or below the 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location of the new selection depending on how the selection is moving. 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The selection will then be pinned to the visible part of the screen, 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * excluding the edges that are faded. The grid is then filled upwards and 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * downwards from there. 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param delta Which way we are moving 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenTop Where to start drawing children 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenBottom Last pixel where children can be drawn 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The view that currently has selection 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View moveSelection(int delta, int childrenTop, int childrenBottom) { 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int fadingEdgeLength = getVerticalFadingEdgeLength(); 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = mSelectedPosition; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int verticalSpacing = mVerticalSpacing; 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int oldRowStart; 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowStart; 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowEnd = -1; 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldRowStart = (selectedPosition - delta) - ((selectedPosition - delta) % numColumns); 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = selectedPosition - (selectedPosition % numColumns); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int invertedSelection = mItemCount - 1 - selectedPosition; 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = Math.max(0, rowEnd - numColumns + 1); 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invertedSelection = mItemCount - 1 - (selectedPosition - delta); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldRowStart = mItemCount - 1 - (invertedSelection - (invertedSelection % numColumns)); 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldRowStart = Math.max(0, oldRowStart - numColumns + 1); 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowDelta = rowStart - oldRowStart; 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int topSelectionPixel = getTopSelectionPixel(childrenTop, fadingEdgeLength, rowStart); 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int bottomSelectionPixel = getBottomSelectionPixel(childrenBottom, fadingEdgeLength, 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project numColumns, rowStart); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Possibly changed again in fillUp if we add rows above this one. 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = rowStart; 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View sel; 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View referenceView; 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rowDelta > 0) { 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Case 1: Scrolling down. 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int oldBottom = mReferenceViewInSelectedRow == null ? 0 : 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReferenceViewInSelectedRow.getBottom(); 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = makeRow(mStackFromBottom ? rowEnd : rowStart, oldBottom + verticalSpacing, true); 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenceView = mReferenceView; 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustForBottomFadingEdge(referenceView, topSelectionPixel, bottomSelectionPixel); 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (rowDelta < 0) { 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Case 2: Scrolling up. 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int oldTop = mReferenceViewInSelectedRow == null ? 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0 : mReferenceViewInSelectedRow .getTop(); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = makeRow(mStackFromBottom ? rowEnd : rowStart, oldTop - verticalSpacing, false); 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenceView = mReferenceView; 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustForTopFadingEdge(referenceView, topSelectionPixel, bottomSelectionPixel); 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Keep selection where it was 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int oldTop = mReferenceViewInSelectedRow == null ? 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0 : mReferenceViewInSelectedRow .getTop(); 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = makeRow(mStackFromBottom ? rowEnd : rowStart, oldTop, true); 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenceView = mReferenceView; 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - numColumns, referenceView.getTop() - verticalSpacing); 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowStart + numColumns, referenceView.getBottom() + verticalSpacing); 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillDown(rowEnd + numColumns, referenceView.getBottom() + verticalSpacing); 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fillUp(rowStart - 1, referenceView.getTop() - verticalSpacing); 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sel; 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 928edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski private boolean determineColumns(int availableSpace) { 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int requestedHorizontalSpacing = mRequestedHorizontalSpacing; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int stretchMode = mStretchMode; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int requestedColumnWidth = mRequestedColumnWidth; 932edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski boolean didNotInitiallyFit = false; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRequestedNumColumns == AUTO_FIT) { 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (requestedColumnWidth > 0) { 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Client told us to pick the number of columns 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumColumns = (availableSpace + requestedHorizontalSpacing) / 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (requestedColumnWidth + requestedHorizontalSpacing); 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Just make up a number if we don't have enough info 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumColumns = 2; 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We picked the columns 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumColumns = mRequestedNumColumns; 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNumColumns <= 0) { 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNumColumns = 1; 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (stretchMode) { 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case NO_STRETCH: 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Nobody stretches 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnWidth = requestedColumnWidth; 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing; 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int spaceLeftOver = availableSpace - (mNumColumns * requestedColumnWidth) - 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mNumColumns - 1) * requestedHorizontalSpacing); 962edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski 963edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski if (spaceLeftOver < 0) { 964edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski didNotInitiallyFit = true; 965edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski } 966edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (stretchMode) { 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STRETCH_COLUMN_WIDTH: 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Stretch the columns 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnWidth = requestedColumnWidth + spaceLeftOver / mNumColumns; 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing; 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STRETCH_SPACING: 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Stretch the spacing between columns 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnWidth = requestedColumnWidth; 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNumColumns > 1) { 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing + 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spaceLeftOver / (mNumColumns - 1); 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing + spaceLeftOver; 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case STRETCH_SPACING_UNIFORM: 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Stretch the spacing between columns 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mColumnWidth = requestedColumnWidth; 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNumColumns > 1) { 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing + 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project spaceLeftOver / (mNumColumns + 1); 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHorizontalSpacing = requestedHorizontalSpacing + spaceLeftOver; 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 999edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski return didNotInitiallyFit; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sets up mListPadding 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onMeasure(widthMeasureSpec, heightMeasureSpec); 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthMode = MeasureSpec.getMode(widthMeasureSpec); 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int heightMode = MeasureSpec.getMode(heightMeasureSpec); 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int widthSize = MeasureSpec.getSize(widthMeasureSpec); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int heightSize = MeasureSpec.getSize(heightMeasureSpec); 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (widthMode == MeasureSpec.UNSPECIFIED) { 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mColumnWidth > 0) { 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthSize = mColumnWidth + mListPadding.left + mListPadding.right; 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthSize = mListPadding.left + mListPadding.right; 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widthSize += getVerticalScrollbarWidth(); 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childWidth = widthSize - mListPadding.left - mListPadding.right; 1022edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski boolean didNotInitiallyFit = determineColumns(childWidth); 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childHeight = 0; 1025189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn int childState = 0; 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mItemCount = mAdapter == null ? 0 : mAdapter.getCount(); 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = mItemCount; 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count > 0) { 103021875052adddf2b52bc57fea62bf097b8aa04cbfRomain Guy final View child = obtainView(0, mIsScrap); 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1032aebd28f729fa28016d70551d0372ab7fcd56ee1aAdam Powell AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams(); 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 1034aebd28f729fa28016d70551d0372ab7fcd56ee1aAdam Powell p = (AbsListView.LayoutParams) generateDefaultLayoutParams(); 10354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project child.setLayoutParams(p); 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.viewType = mAdapter.getItemViewType(0); 10380bf88594c43ced48d862d122e3e84967b3b63658Romain Guy p.forceAdd = true; 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childHeightSpec = getChildMeasureSpec( 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height); 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childWidthSpec = getChildMeasureSpec( 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width); 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.measure(childWidthSpec, childHeightSpec); 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childHeight = child.getMeasuredHeight(); 1047189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn childState = combineMeasuredStates(childState, child.getMeasuredState()); 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRecycler.shouldRecycleViewType(p.viewType)) { 1050079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn mRecycler.addScrapView(child, -1); 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (heightMode == MeasureSpec.UNSPECIFIED) { 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heightSize = mListPadding.top + mListPadding.bottom + childHeight + 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getVerticalFadingEdgeLength() * 2; 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (heightMode == MeasureSpec.AT_MOST) { 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ourSize = mListPadding.top + mListPadding.bottom; 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < count; i += numColumns) { 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ourSize += childHeight; 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i + numColumns < count) { 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ourSize += mVerticalSpacing; 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ourSize >= heightSize) { 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ourSize = heightSize; 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heightSize = ourSize; 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1076189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn if (widthMode == MeasureSpec.AT_MOST && mRequestedNumColumns != AUTO_FIT) { 1077189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn int ourSize = (mRequestedNumColumns*mColumnWidth) 1078189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn + ((mRequestedNumColumns-1)*mHorizontalSpacing) 1079189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn + mListPadding.left + mListPadding.right; 1080edd9508aba83a0e6ed49cce3840783c1c72d1430Adam Lesinski if (ourSize > widthSize || didNotInitiallyFit) { 1081189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn widthSize |= MEASURED_STATE_TOO_SMALL; 1082189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn } 1083189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn } 1084189ee18d6c6483ad63cc864267328259e2e00b95Dianne Hackborn 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setMeasuredDimension(widthSize, heightSize); 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWidthMeasureSpec = widthMeasureSpec; 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void attachLayoutAnimationParameters(View child, 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.LayoutParams params, int index, int count) { 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GridLayoutAnimationController.AnimationParameters animationParams = 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (GridLayoutAnimationController.AnimationParameters) params.layoutAnimationParameters; 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (animationParams == null) { 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams = new GridLayoutAnimationController.AnimationParameters(); 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params.layoutAnimationParameters = animationParams; 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.count = count; 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.index = index; 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.columnsCount = mNumColumns; 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.rowsCount = count / mNumColumns; 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.column = index % mNumColumns; 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.row = index / mNumColumns; 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedIndex = count - 1 - index; 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.column = mNumColumns - 1 - (invertedIndex % mNumColumns); 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project animationParams.row = animationParams.rowsCount - 1 - invertedIndex / mNumColumns; 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void layoutChildren() { 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean blockLayoutRequests = mBlockLayoutRequests; 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!blockLayoutRequests) { 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBlockLayoutRequests = true; 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.layoutChildren(); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invalidate(); 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdapter == null) { 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resetList(); 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childrenTop = mListPadding.top; 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childrenBottom = mBottom - mTop - mListPadding.bottom; 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childCount = getChildCount(); 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index; 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int delta = 0; 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View sel; 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View oldSel = null; 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View oldFirst = null; 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View newSel = null; 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remember stuff we will need down below 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (mLayoutMode) { 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SET_SELECTION: 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = mNextSelectedPosition - mFirstPosition; 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0 && index < childCount) { 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newSel = getChildAt(index); 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_FORCE_TOP: 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_FORCE_BOTTOM: 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SPECIFIC: 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SYNC: 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_MOVE_SELECTION: 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextSelectedPosition >= 0) { 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = mNextSelectedPosition - mSelectedPosition; 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remember the previously selected view 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project index = mSelectedPosition - mFirstPosition; 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index >= 0 && index < childCount) { 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldSel = getChildAt(index); 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remember the previous first child 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldFirst = getChildAt(0); 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean dataChanged = mDataChanged; 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dataChanged) { 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleDataChanged(); 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Handle the empty set by removing all views that are visible 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and calling it a day 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mItemCount == 0) { 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resetList(); 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectedPositionInt(mNextSelectedPosition); 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Pull all children into the RecycleBin. 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // These views will be reused if possible 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int firstPosition = mFirstPosition; 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final RecycleBin recycleBin = mRecycler; 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dataChanged) { 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < childCount; i++) { 1198079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn recycleBin.addScrapView(getChildAt(i), firstPosition+i); 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project recycleBin.fillActiveViews(childCount, firstPosition); 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Clear out old views 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //removeAllViewsInLayout(); 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project detachAllViewsFromParent(); 1207539ee8716b4f81260bab2e9f3dc5d88d81c99985Adam Powell recycleBin.removeSkippedScrap(); 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (mLayoutMode) { 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SET_SELECTION: 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newSel != null) { 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillFromSelection(newSel.getTop(), childrenTop, childrenBottom); 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSelection(childrenTop, childrenBottom); 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_FORCE_TOP: 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFirstPosition = 0; 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillFromTop(childrenTop); 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_FORCE_BOTTOM: 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillUp(mItemCount - 1, childrenBottom); 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project adjustViewsUpOrDown(); 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SPECIFIC: 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(mSelectedPosition, mSpecificTop); 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_SYNC: 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(mSyncPosition, mSpecificTop); 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case LAYOUT_MOVE_SELECTION: 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Move the selection relative to its old position 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = moveSelection(delta, childrenTop, childrenBottom); 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount == 0) { 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 123991c8613679959a5fde4f72fe6dd80023d9a1a9e7Romain Guy setSelectedPositionInt(mAdapter == null || isInTouchMode() ? 124091c8613679959a5fde4f72fe6dd80023d9a1a9e7Romain Guy INVALID_POSITION : 0); 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillFromTop(childrenTop); 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int last = mItemCount - 1; 124491c8613679959a5fde4f72fe6dd80023d9a1a9e7Romain Guy setSelectedPositionInt(mAdapter == null || isInTouchMode() ? 124591c8613679959a5fde4f72fe6dd80023d9a1a9e7Romain Guy INVALID_POSITION : last); 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillFromBottom(last, childrenBottom); 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mSelectedPosition >= 0 && mSelectedPosition < mItemCount) { 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(mSelectedPosition, oldSel == null ? 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childrenTop : oldSel.getTop()); 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mFirstPosition < mItemCount) { 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(mFirstPosition, oldFirst == null ? 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childrenTop : oldFirst.getTop()); 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sel = fillSpecific(0, childrenTop); 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Flush any cached views that did not get reused above 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project recycleBin.scrapActiveViews(); 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sel != null) { 1266079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn positionSelector(INVALID_POSITION, sel); 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSelectedTop = sel.getTop(); 12683616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy } else if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) { 12693616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy View child = getChildAt(mMotionPosition - mFirstPosition); 1270079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (child != null) positionSelector(mMotionPosition, child); 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12723616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy mSelectedTop = 0; 12733616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy mSelectorRect.setEmpty(); 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_NORMAL; 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataChanged = false; 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNeedSync = false; 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNextSelectedPositionInt(mSelectedPosition); 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateScrollIndicators(); 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mItemCount > 0) { 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkSelectionChanged(); 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!blockLayoutRequests) { 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBlockLayoutRequests = false; 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Obtain the view and add it to our list of children. The view can be made 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fresh, converted from an unused view, or used as is if it was in the 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * recycle bin. 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position Logical position in the list 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y Top or bottom edge of the view to add 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flow if true, align top edge to y. If false, align bottom edge to 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * y. 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenLeft Left edge where children should be positioned 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selected Is this position selected? 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where to add new item in the list 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return View that was added 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private View makeAndAddView(int position, int y, boolean flow, int childrenLeft, 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean selected, int where) { 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View child; 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDataChanged) { 131521875052adddf2b52bc57fea62bf097b8aa04cbfRomain Guy // Try to use an existing view for this position 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child = mRecycler.getActiveView(position); 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (child != null) { 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Found it -- we're using an existing child 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This just needs to be positioned 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setupChild(child, position, y, flow, childrenLeft, selected, true, where); 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return child; 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make a new view for this position, or convert an unused view if 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // possible 132721875052adddf2b52bc57fea62bf097b8aa04cbfRomain Guy child = obtainView(position, mIsScrap); 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This needs to be positioned and measured 133021875052adddf2b52bc57fea62bf097b8aa04cbfRomain Guy setupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0], where); 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return child; 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Add a view as a child and make sure it is measured (if necessary) and 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * positioned properly. 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param child The view to add 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position The position of the view 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y The y position relative to which this view will be positioned 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flow if true, align top edge to y. If false, align bottom edge 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to y. 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childrenLeft Left edge where children should be positioned 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param selected Is this position selected? 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param recycled Has this view been pulled from the recycle bin? If so it 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * does not need to be remeasured. 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param where Where to add the item in the list 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void setupChild(View child, int position, int y, boolean flow, int childrenLeft, 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean selected, boolean recycled, int where) { 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isSelected = selected && shouldShowSelector(); 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final boolean updateChildSelected = isSelected != child.isSelected(); 13553616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy final int mode = mTouchMode; 13563616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy final boolean isPressed = mode > TOUCH_MODE_DOWN && mode < TOUCH_MODE_SCROLL && 13573616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy mMotionPosition == position; 13583616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy final boolean updateChildPressed = isPressed != child.isPressed(); 13593616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean needToMeasure = !recycled || updateChildSelected || child.isLayoutRequested(); 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Respect layout params that are already in the view. Otherwise make 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // some up... 1364aebd28f729fa28016d70551d0372ab7fcd56ee1aAdam Powell AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams(); 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 1366aebd28f729fa28016d70551d0372ab7fcd56ee1aAdam Powell p = (AbsListView.LayoutParams) generateDefaultLayoutParams(); 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.viewType = mAdapter.getItemViewType(position); 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13700bf88594c43ced48d862d122e3e84967b3b63658Romain Guy if (recycled && !p.forceAdd) { 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project attachViewToParent(child, where, p); 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13730bf88594c43ced48d862d122e3e84967b3b63658Romain Guy p.forceAdd = false; 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addViewInLayout(child, where, p, true); 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (updateChildSelected) { 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.setSelected(isSelected); 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isSelected) { 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestFocus(); 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13843616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy if (updateChildPressed) { 13853616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy child.setPressed(isPressed); 13863616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy } 13873616a412cbd620168fd87ce83978d83a9c0621c6Romain Guy 1388f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) { 1389f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell if (child instanceof Checkable) { 1390f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell ((Checkable) child).setChecked(mCheckStates.get(position)); 1391d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn } else if (getContext().getApplicationInfo().targetSdkVersion 1392d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn >= android.os.Build.VERSION_CODES.HONEYCOMB) { 1393d0fa371f276fde32d81c037006941bc93da0bb03Dianne Hackborn child.setActivated(mCheckStates.get(position)); 1394f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell } 1395f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell } 1396f343e1ba7e796120eefa917dbf78348feea98e11Adam Powell 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (needToMeasure) { 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childHeightSpec = ViewGroup.getChildMeasureSpec( 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height); 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childWidthSpec = ViewGroup.getChildMeasureSpec( 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width); 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.measure(childWidthSpec, childHeightSpec); 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cleanupLayoutState(child); 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int w = child.getMeasuredWidth(); 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int h = child.getMeasuredHeight(); 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int childLeft; 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childTop = flow ? y : y - h; 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1414c0053223bedf33581b0830fb87be32c1f26e5372Fabrice Di Meglio final int layoutDirection = getResolvedLayoutDirection(); 1415c0053223bedf33581b0830fb87be32c1f26e5372Fabrice Di Meglio final int absoluteGravity = Gravity.getAbsoluteGravity(mGravity, layoutDirection); 14166a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { 14176a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio case Gravity.LEFT: 14186a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio childLeft = childrenLeft; 14196a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio break; 14206a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio case Gravity.CENTER_HORIZONTAL: 14216a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio childLeft = childrenLeft + ((mColumnWidth - w) / 2); 14226a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio break; 14236a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio case Gravity.RIGHT: 14246a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio childLeft = childrenLeft + mColumnWidth - w; 14256a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio break; 14266a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio default: 14276a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio childLeft = childrenLeft; 14286a03640539405afbdefe72894759281b98aa6e6fFabrice Di Meglio break; 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (needToMeasure) { 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childRight = childLeft + w; 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childBottom = childTop + h; 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.layout(childLeft, childTop, childRight, childBottom); 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.offsetLeftAndRight(childLeft - child.getLeft()); 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.offsetTopAndBottom(childTop - child.getTop()); 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCachingStarted) { 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child.setDrawingCacheEnabled(true); 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1443079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn 1444079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn if (recycled && (((AbsListView.LayoutParams)child.getLayoutParams()).scrappedFromPosition) 1445079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn != position) { 1446079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn child.jumpDrawablesToCurrentState(); 1447079e23575024e103358c982152afb7a720ae1a8aDianne Hackborn } 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the currently selected item 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position Index (starting at 0) of the data item to be selected. 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If in touch mode, the item will not be selected but it will still be positioned 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * appropriately. 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setSelection(int position) { 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isInTouchMode()) { 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNextSelectedPositionInt(position); 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResurrectToPosition = position; 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_SET_SELECTION; 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Makes the item at the supplied position selected. 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param position the position of the new selection 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void setSelectionInt(int position) { 1476f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron int previousSelectedPosition = mNextSelectedPosition; 1477f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setNextSelectedPositionInt(position); 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project layoutChildren(); 1480f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron 1481f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron final int next = mStackFromBottom ? mItemCount - 1 - mNextSelectedPosition : 1482f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron mNextSelectedPosition; 1483f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron final int previous = mStackFromBottom ? mItemCount - 1 1484f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron - previousSelectedPosition : previousSelectedPosition; 1485f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron 1486f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron final int nextRow = next / mNumColumns; 1487f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron final int previousRow = previous / mNumColumns; 1488f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron 1489f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron if (nextRow != previousRow) { 1490f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron awakenScrollBars(); 1491f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron } 1492f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return commonKey(keyCode, 1, event); 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return commonKey(keyCode, repeatCount, event); 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return commonKey(keyCode, 1, event); 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean commonKey(int keyCode, int count, KeyEvent event) { 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mAdapter == null) { 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataChanged) { 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project layoutChildren(); 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean handled = false; 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int action = event.getAction(); 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (action != KeyEvent.ACTION_UP) { 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (keyCode) { 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_LEFT: 15254e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 15268d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_LEFT); 15274e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_RIGHT: 15314e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 15328d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_RIGHT); 15334e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_UP: 15374e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 15388d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_UP); 15394e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) { 15408d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_UP); 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_DOWN: 15454e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 15468d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || arrowScroll(FOCUS_DOWN); 15474e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) { 15488d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_DOWN); 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 15538d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown case KeyEvent.KEYCODE_ENTER: 15548d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown if (event.hasNoModifiers()) { 15558d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded(); 15568d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown if (!handled 15578d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown && event.getRepeatCount() == 0 && getChildCount() > 0) { 15588d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown keyPressed(); 15598d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = true; 15608d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown } 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15628d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown break; 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case KeyEvent.KEYCODE_SPACE: 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPopup == null || !mPopup.isShowing()) { 15664e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 15678d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_DOWN); 15684e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) { 15698d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_UP); 15704e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 15714e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 15724e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown break; 15734e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 15744e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown case KeyEvent.KEYCODE_PAGE_UP: 15754e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 15768d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_UP); 15774e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) { 15788d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_UP); 15794e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 15804e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown break; 15814e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 15824e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown case KeyEvent.KEYCODE_PAGE_DOWN: 15834e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 15848d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || pageScroll(FOCUS_DOWN); 15854e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } else if (event.hasModifiers(KeyEvent.META_ALT_ON)) { 15868d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_DOWN); 15874e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 15884e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown break; 15894e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 15904e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown case KeyEvent.KEYCODE_MOVE_HOME: 15914e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 15928d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_UP); 15934e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 15944e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown break; 15954e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 15964e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown case KeyEvent.KEYCODE_MOVE_END: 15974e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 15988d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() || fullScroll(FOCUS_DOWN); 15994e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 16004e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown break; 16014e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 16024e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown case KeyEvent.KEYCODE_TAB: 16034e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // XXX Sometimes it is useful to be able to TAB through the items in 16044e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // a GridView sequentially. Unfortunately this can create an 16054e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // asymmetry in TAB navigation order unless the list selection 16064e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // always reverts to the top or bottom when receiving TAB focus from 16074e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // another widget. Leaving this behavior disabled for now but 16084e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // perhaps it should be configurable (and more comprehensive). 16094e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (false) { 16104e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (event.hasNoModifiers()) { 16118d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() 16128d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown || sequenceScroll(FOCUS_FORWARD); 16134e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } else if (event.hasModifiers(KeyEvent.META_SHIFT_ON)) { 16148d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown handled = resurrectSelectionIfNeeded() 16158d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown || sequenceScroll(FOCUS_BACKWARD); 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16228d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown if (handled) { 16238d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown return true; 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16268d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown if (sendToTextFilter(keyCode, count, event)) { 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 16288d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown } 16298d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown 16308d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown switch (action) { 16318d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown case KeyEvent.ACTION_DOWN: 16328d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown return super.onKeyDown(keyCode, event); 16338d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown case KeyEvent.ACTION_UP: 16348d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown return super.onKeyUp(keyCode, event); 16358d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown case KeyEvent.ACTION_MULTIPLE: 16368d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown return super.onKeyMultiple(keyCode, count, event); 16378d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown default: 16388d6d3b83fb765eefc6fd38de77f1f45d2523ab89Jeff Brown return false; 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Scrolls up or down by the number of items currently present on screen. 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param direction either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return whether selection was moved 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean pageScroll(int direction) { 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int nextPage = -1; 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (direction == FOCUS_UP) { 165264d50a67f44f6f8627b6d5203f0e3b26dc4f71e5Romain Guy nextPage = Math.max(0, mSelectedPosition - getChildCount()); 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (direction == FOCUS_DOWN) { 165464d50a67f44f6f8627b6d5203f0e3b26dc4f71e5Romain Guy nextPage = Math.min(mItemCount - 1, mSelectedPosition + getChildCount()); 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (nextPage >= 0) { 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(nextPage); 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 1660f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron awakenScrollBars(); 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Go to the last or first item if possible. 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param direction either {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN}. 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether selection was moved. 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean fullScroll(int direction) { 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean moved = false; 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (direction == FOCUS_UP) { 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_SET_SELECTION; 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(0); 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (direction == FOCUS_DOWN) { 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_SET_SELECTION; 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(mItemCount - 1); 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1687f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron 1688f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron if (moved) { 1689f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron awakenScrollBars(); 1690f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron } 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return moved; 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Scrolls to the next or previous item, horizontally or vertically. 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param direction either {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT}, 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link View#FOCUS_UP} or {@link View#FOCUS_DOWN} 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return whether selection was moved 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean arrowScroll(int direction) { 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int selectedPosition = mSelectedPosition; 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int startOfRowPos; 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int endOfRowPos; 17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean moved = false; 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startOfRowPos = (selectedPosition / numColumns) * numColumns; 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endOfRowPos = Math.min(startOfRowPos + numColumns - 1, mItemCount - 1); 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedSelection = mItemCount - 1 - selectedPosition; 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project endOfRowPos = mItemCount - 1 - (invertedSelection / numColumns) * numColumns; 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startOfRowPos = Math.max(0, endOfRowPos - numColumns + 1); 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (direction) { 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FOCUS_UP: 17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (startOfRowPos > 0) { 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_MOVE_SELECTION; 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(Math.max(0, selectedPosition - numColumns)); 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FOCUS_DOWN: 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (endOfRowPos < mItemCount - 1) { 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_MOVE_SELECTION; 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelectionInt(Math.min(selectedPosition + numColumns, mItemCount - 1)); 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FOCUS_LEFT: 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selectedPosition > startOfRowPos) { 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_MOVE_SELECTION; 173951d154b82b5ed95edb0a869414ecbcd4faa6a62cRomain Guy setSelectionInt(Math.max(0, selectedPosition - 1)); 17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FOCUS_RIGHT: 17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (selectedPosition < endOfRowPos) { 17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLayoutMode = LAYOUT_MOVE_SELECTION; 174651d154b82b5ed95edb0a869414ecbcd4faa6a62cRomain Guy setSelectionInt(Math.min(selectedPosition + 1, mItemCount - 1)); 17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project moved = true; 17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (moved) { 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction)); 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeOnItemScrollListener(); 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1757f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron if (moved) { 1758f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron awakenScrollBars(); 1759f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron } 1760f116bf8884b5b58aae261d148003811aa4a7c6e9Mike Cleron 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return moved; 17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17644e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown /** 17654e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown * Goes to the next or previous item according to the order set by the 17664e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown * adapter. 17674e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown */ 17684e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown boolean sequenceScroll(int direction) { 17694e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown int selectedPosition = mSelectedPosition; 17704e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown int numColumns = mNumColumns; 17714e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown int count = mItemCount; 17724e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 17734e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown int startOfRow; 17744e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown int endOfRow; 17754e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (!mStackFromBottom) { 17764e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown startOfRow = (selectedPosition / numColumns) * numColumns; 17774e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown endOfRow = Math.min(startOfRow + numColumns - 1, count - 1); 17784e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } else { 17794e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown int invertedSelection = count - 1 - selectedPosition; 17804e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown endOfRow = count - 1 - (invertedSelection / numColumns) * numColumns; 17814e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown startOfRow = Math.max(0, endOfRow - numColumns + 1); 17824e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 17834e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 17844e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown boolean moved = false; 17854e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown boolean showScroll = false; 17864e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown switch (direction) { 17874e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown case FOCUS_FORWARD: 17884e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (selectedPosition < count - 1) { 17894e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // Move to the next item. 17904e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown mLayoutMode = LAYOUT_MOVE_SELECTION; 17914e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown setSelectionInt(selectedPosition + 1); 17924e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown moved = true; 17934e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // Show the scrollbar only if changing rows. 17944e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown showScroll = selectedPosition == endOfRow; 17954e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 17964e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown break; 17974e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 17984e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown case FOCUS_BACKWARD: 17994e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (selectedPosition > 0) { 18004e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // Move to the previous item. 18014e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown mLayoutMode = LAYOUT_MOVE_SELECTION; 18024e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown setSelectionInt(selectedPosition - 1); 18034e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown moved = true; 18044e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // Show the scrollbar only if changing rows. 18054e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown showScroll = selectedPosition == startOfRow; 18064e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 18074e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown break; 18084e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 18094e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 18104e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (moved) { 18114e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction)); 18124e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown invokeOnItemScrollListener(); 18134e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 18144e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 18154e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown if (showScroll) { 18164e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown awakenScrollBars(); 18174e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 18184e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 18194e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown return moved; 18204e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown } 18214e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { 18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int closestChildIndex = -1; 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (gainFocus && previouslyFocusedRect != null) { 18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project previouslyFocusedRect.offset(mScrollX, mScrollY); 18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // figure out which item should be selected based on previously 18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // focused rect 18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect otherRect = mTempRect; 18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int minDistance = Integer.MAX_VALUE; 18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < childCount; i++) { 18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // only consider view's on appropriate edge of grid 18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isCandidateSelection(i, direction)) { 18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View other = getChildAt(i); 18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project other.getDrawingRect(otherRect); 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetDescendantRectToMyCoords(other, otherRect); 18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int distance = getDistance(previouslyFocusedRect, otherRect, direction); 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (distance < minDistance) { 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minDistance = distance; 18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project closestChildIndex = i; 18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (closestChildIndex >= 0) { 18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setSelection(closestChildIndex + mFirstPosition); 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayout(); 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Is childIndex a candidate for next focus given the direction the focus 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * change is coming from? 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param childIndex The index to check. 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param direction The direction, one of 18654e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown * {FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, FOCUS_FORWARD, FOCUS_BACKWARD} 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Whether childIndex is a candidate. 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isCandidateSelection(int childIndex, int direction) { 18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int invertedIndex = count - 1 - childIndex; 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowStart; 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rowEnd; 18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = childIndex - (childIndex % mNumColumns); 18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = Math.max(rowStart + mNumColumns - 1, count); 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEnd = count - 1 - (invertedIndex - (invertedIndex % mNumColumns)); 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowStart = Math.max(0, rowEnd - mNumColumns + 1); 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (direction) { 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.FOCUS_RIGHT: 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // coming from left, selection is only valid if it is on left 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // edge 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return childIndex == rowStart; 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.FOCUS_DOWN: 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // coming from top; only valid if in top row 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return rowStart == 0; 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.FOCUS_LEFT: 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // coming from right, must be on right edge 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return childIndex == rowEnd; 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case View.FOCUS_UP: 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // coming from bottom, need to be in last row 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return rowEnd == count - 1; 18974e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown case View.FOCUS_FORWARD: 18984e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // coming from top-left, need to be first in top row 18994e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown return childIndex == rowStart && rowStart == 0; 19004e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown case View.FOCUS_BACKWARD: 19014e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown // coming from bottom-right, need to be last in bottom row 19024e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown return childIndex == rowEnd && rowEnd == count - 1; 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("direction must be one of " 19054e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown + "{FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, FOCUS_RIGHT, " 19064e6319b73c85082e18d1c532b86336ddd1f8cfaaJeff Brown + "FOCUS_FORWARD, FOCUS_BACKWARD}."); 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Describes how the child views are horizontally aligned. Defaults to Gravity.LEFT 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param gravity the gravity to apply to this grid's children 19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_gravity 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setGravity(int gravity) { 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGravity != gravity) { 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGravity = gravity; 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the amount of horizontal (x) spacing to place between each item 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the grid. 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param horizontalSpacing The amount of horizontal space between items, 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in pixels. 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_horizontalSpacing 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setHorizontalSpacing(int horizontalSpacing) { 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (horizontalSpacing != mRequestedHorizontalSpacing) { 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRequestedHorizontalSpacing = horizontalSpacing; 19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the amount of vertical (y) spacing to place between each item 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in the grid. 19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param verticalSpacing The amount of vertical space between items, 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in pixels. 19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_verticalSpacing 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setVerticalSpacing(int verticalSpacing) { 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (verticalSpacing != mVerticalSpacing) { 19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVerticalSpacing = verticalSpacing; 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Control how items are stretched to fill their space. 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param stretchMode Either {@link #NO_STRETCH}, 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #STRETCH_SPACING}, {@link #STRETCH_SPACING_UNIFORM}, or {@link #STRETCH_COLUMN_WIDTH}. 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_stretchMode 19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setStretchMode(int stretchMode) { 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (stretchMode != mStretchMode) { 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStretchMode = stretchMode; 19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStretchMode() { 19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStretchMode; 19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the width of columns in the grid. 19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columnWidth The column width, in pixels. 19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_columnWidth 19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setColumnWidth(int columnWidth) { 19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (columnWidth != mRequestedColumnWidth) { 19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRequestedColumnWidth = columnWidth; 19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the number of columns in the grid 19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param numColumns The desired number of columns. 19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#GridView_numColumns 19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setNumColumns(int numColumns) { 19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numColumns != mRequestedNumColumns) { 19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRequestedNumColumns = numColumns; 20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requestLayoutIfNecessary(); 20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20038d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein 20048d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein /** 20058d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein * Get the number of columns in the grid. 20068d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein * Returns {@link #AUTO_FIT} if the Grid has never been laid out. 20078d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein * 20088d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein * @attr ref android.R.styleable#GridView_numColumns 20098d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein * 20108d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein * @see #setNumColumns(int) 20118d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein */ 20128d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein @ViewDebug.ExportedProperty 20138d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein public int getNumColumns() { 20148d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein return mNumColumns; 20158d9db8e4c774bb75bc8c08cc5309a7c0712ce017Andrew Sapperstein } 20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Make sure views are touching the top or bottom edge, as appropriate for 20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * our gravity 20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 20219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void adjustViewsUpOrDown() { 20229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int childCount = getChildCount(); 20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (childCount > 0) { 20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int delta; 20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View child; 20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStackFromBottom) { 20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Uh-oh -- we came up short. Slide all views up to make them 20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // align with the top 20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child = getChildAt(0); 20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = child.getTop() - mListPadding.top; 20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition != 0) { 20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It's OK to have some space above the first item if it is 20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // part of the vertical spacing 20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta -= mVerticalSpacing; 20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (delta < 0) { 20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We only are looking to see if we are too low, not too high 20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = 0; 20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we are too high, slide all views down to align with bottom 20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project child = getChildAt(childCount - 1); 20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = child.getBottom() - (getHeight() - mListPadding.bottom); 20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition + childCount < mItemCount) { 20489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It's OK to have some space below the last item if it is 20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // part of the vertical spacing 20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta += mVerticalSpacing; 20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (delta > 0) { 20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We only are looking to see if we are too high, not too low 20559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delta = 0; 20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (delta != 0) { 20609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project offsetChildrenTopAndBottom(-delta); 20619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 20669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int computeVerticalScrollExtent() { 20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int count = getChildCount(); 20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count > 0) { 20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 20709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowCount = (count + numColumns - 1) / numColumns; 20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int extent = rowCount * 100; 20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View view = getChildAt(0); 20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int top = view.getTop(); 20769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int height = view.getHeight(); 20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height > 0) { 20789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extent += (top * 100) / height; 20799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view = getChildAt(count - 1); 20829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int bottom = view.getBottom(); 20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project height = view.getHeight(); 20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height > 0) { 20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extent -= ((bottom - getHeight()) * 100) / height; 20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return extent; 20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int computeVerticalScrollOffset() { 20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFirstPosition >= 0 && getChildCount() > 0) { 20969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View view = getChildAt(0); 20979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int top = view.getTop(); 20989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int height = view.getHeight(); 20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (height > 0) { 2100f2a204e792df5593cfe54efc95d04b7e764795c1Adam Powell final int numColumns = mNumColumns; 2101f2a204e792df5593cfe54efc95d04b7e764795c1Adam Powell final int whichRow = mFirstPosition / numColumns; 2102f2a204e792df5593cfe54efc95d04b7e764795c1Adam Powell final int rowCount = (mItemCount + numColumns - 1) / numColumns; 2103f2a204e792df5593cfe54efc95d04b7e764795c1Adam Powell return Math.max(whichRow * 100 - (top * 100) / height + 2104f2a204e792df5593cfe54efc95d04b7e764795c1Adam Powell (int) ((float) mScrollY / getHeight() * rowCount * 100), 0); 21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 21089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int computeVerticalScrollRange() { 21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: Account for vertical spacing too 21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int numColumns = mNumColumns; 21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int rowCount = (mItemCount + numColumns - 1) / numColumns; 2115637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell int result = Math.max(rowCount * 100, 0); 2116637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell if (mScrollY != 0) { 2117637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell // Compensate for overscroll 2118637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell result += Math.abs((int) ((float) mScrollY / getHeight() * rowCount * 100)); 2119637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell } 2120637d337b58d8eec6de19230a5dd5ca5581c0478dAdam Powell return result; 21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21238a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 21248a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityEvent(AccessibilityEvent event) { 21258a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityEvent(event); 21268a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov event.setClassName(GridView.class.getName()); 21278a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 21288a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov 21298a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov @Override 21308a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 21318a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov super.onInitializeAccessibilityNodeInfo(info); 21328a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov info.setClassName(GridView.class.getName()); 21338a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov } 21348a78fd4d9572dff95432fcc4ba0e87563415b728Svetoslav Ganov} 2135